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 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
112 const TopTools_IndexedMapOfShape &theIndices,
113 Handle(TColStd_HArray1OfInteger) *theGroupIds);
115 static void StoreGroups(GEOMImpl_IPipe *theCI,
116 Handle(TColStd_HArray1OfInteger) *theGroups);
118 static bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
119 TopTools_SequenceOfShape *theGroups);
121 static bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
122 GEOMImpl_IPipe *theCI);
124 //=======================================================================
127 //=======================================================================
128 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
130 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
134 //=======================================================================
135 //function : GEOMImpl_PipeDriver
137 //=======================================================================
138 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
142 //=======================================================================
143 //function : EvaluateBestSweepMode
144 //purpose : auxilary for right call of MakePipe and MakePipeShell
145 //=======================================================================
146 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
148 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
150 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
151 for (; Explo.More(); Explo.Next())
153 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
154 Standard_Real fpar, lpar;
155 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
156 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
157 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
159 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
160 aCorrFrenet->SetCurve(GAHcurve);
161 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
162 if (aMode == GeomFill_IsDiscreteTrihedron)
167 if (aMode == GeomFill_IsCorrectedFrenet)
174 //=======================================================================
175 //function : BuildPipeShell
176 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
177 // mode. Returns Standard_True if the building is done successfully.
178 //=======================================================================
179 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
183 Standard_Boolean isDone = theBuilder.IsDone();
186 // Try to use Descrete Trihedron mode.
187 theBuilder.SetDiscreteMode();
189 isDone = theBuilder.IsDone();
195 //=======================================================================
196 //function : FillForOtherEdges
197 //purpose : auxilary for CreatePipeForShellSections()
198 //=======================================================================
199 static bool FillForOtherEdges(const TopoDS_Shape& F1,
200 const TopoDS_Shape& E1,
201 const TopoDS_Shape& V1,
202 TopTools_IndexedDataMapOfShapeShape& FF)
204 //cout<<"FillForOtherEdges"<<endl;
205 // find other pairs for vertexes and edges
206 // creating map of vertex edges for both faces
207 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
208 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
209 if (!FF.Contains(F1))
210 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
211 if (!FF.Contains(E1))
212 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
213 if (!FF.Contains(V1))
214 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
215 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
216 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
217 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
218 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
219 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
221 TopoDS_Edge ES1 = TopoDS::Edge(E1);
222 TopoDS_Edge ES2 = TopoDS::Edge(E2);
223 TopoDS_Shape VS1 = V1;
224 TopoDS_Shape VS2 = V2;
226 ShapeAnalysis_Edge sae;
228 if (!aMapVertEdge1.Contains(VS1))
229 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
230 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
231 //TopoDS_Shape E1next;
232 TopTools_ListIteratorOfListOfShape anIter1(aList1);
233 if (anIter1.Value().IsSame(ES1)) {
236 //E1next = anIter1.Value();
237 if (!aMapVertEdge2.Contains(VS2))
238 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
239 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
240 //TopoDS_Shape E2next;
241 TopTools_ListIteratorOfListOfShape anIter2(aList2);
242 if (anIter2.Value().IsSame(ES2)) {
245 //E2next = anIter2.Value();
246 //ES1 = TopoDS::Edge(E1next);
247 //ES2 = TopoDS::Edge(E2next);
248 ES1 = TopoDS::Edge(anIter1.Value());
249 ES2 = TopoDS::Edge(anIter2.Value());
250 if (!FF.Contains(ES1)) {
253 if (VS1.IsSame(sae.FirstVertex(ES1)))
254 VS1 = sae.LastVertex(ES1);
256 VS1 = sae.FirstVertex(ES1);
257 if (VS2.IsSame(sae.FirstVertex(ES2)))
258 VS2 = sae.LastVertex(ES2);
260 VS2 = sae.FirstVertex(ES2);
263 if (!FF.Contains(VS1)) {
271 //=======================================================================
272 //function : FillCorrespondingEdges
273 //purpose : auxilary for CreatePipeForShellSections()
274 //=======================================================================
275 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
276 const TopoDS_Shape& FS2,
277 const TopoDS_Vertex& aLoc1,
278 const TopoDS_Vertex& aLoc2,
279 const TopoDS_Wire& aWirePath,
280 TopTools_IndexedDataMapOfShapeShape& FF)
282 //cout<<"FillCorrespondingEdges"<<endl;
283 // find corresponding edges
284 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
285 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
286 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
287 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
288 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
289 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
290 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
291 if (theBestMode == GeomFill_IsDiscreteTrihedron)
292 aBuilder.SetDiscreteMode();
293 aBuilder.Add(aWire1, aLoc1);
294 aBuilder.Add(aWire2, aLoc2);
295 if (!aBuilder.IsReady()) {
299 BuildPipeShell(aBuilder);
301 TopoDS_Shape aShape = aBuilder.Shape();
302 ShapeAnalysis_Edge sae;
303 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
304 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
305 TopTools_MapOfShape Vs1,Vs2;
307 exp.Init(FS1, TopAbs_EDGE);
308 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
309 TopoDS_Vertex V11 = sae.FirstVertex(E1);
310 TopoDS_Vertex V21 = sae.LastVertex(E1);
311 gp_Pnt P11 = BRep_Tool::Pnt(V11);
312 gp_Pnt P21 = BRep_Tool::Pnt(V21);
313 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
314 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
315 // find corresponding vertexes from created shape
316 TopoDS_Vertex VN11,VN21;
317 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
318 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
319 gp_Pnt P = BRep_Tool::Pnt(V);
320 if (P.Distance(P11)<tol) {
323 if (P.Distance(P21)<tol) {
327 // find edge contains VN11 and VN21 and corresponding vertexes
328 TopoDS_Vertex VN12,VN22;
329 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
330 TopoDS_Shape F = exp.Current();
331 TopExp_Explorer expe;
333 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
334 TopoDS_Edge E = TopoDS::Edge(expe.Current());
335 TopoDS_Vertex VF = sae.FirstVertex(E);
336 TopoDS_Vertex VL = sae.LastVertex(E);
337 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
343 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
344 TopoDS_Edge E = TopoDS::Edge(expe.Current());
345 TopoDS_Vertex VF = sae.FirstVertex(E);
346 TopoDS_Vertex VL = sae.LastVertex(E);
347 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
349 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
351 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
353 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
359 // find vertexes from FS2 corresponded to VN12 and VN22
360 // and find edge from FS2 contains V12 and V22,
361 // this edge will be corresponded to edge E1
362 TopoDS_Vertex V12,V22;
363 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
364 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
365 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
366 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
368 TopExp_Explorer expe;
369 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
370 TopoDS_Edge E = TopoDS::Edge(expe.Current());
371 TopoDS_Vertex VF = sae.FirstVertex(E);
372 TopoDS_Vertex VL = sae.LastVertex(E);
373 gp_Pnt PF = BRep_Tool::Pnt(VF);
374 gp_Pnt PL = BRep_Tool::Pnt(VL);
375 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
381 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
392 // find other pairs for vertexes and edges
393 // creating map of vertex edges for both faces
394 return FillForOtherEdges(FS1,E1,V21,FF);
399 //=======================================================================
400 //function : FillCorrespondingEdges
401 //purpose : auxilary for CreatePipeShellsWithoutPath()
402 //=======================================================================
403 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
404 const TopoDS_Shape& FS2,
405 const TopoDS_Vertex& aLoc1,
406 const TopoDS_Vertex& aLoc2,
407 TopTools_IndexedDataMapOfShapeShape& FF)
409 //cout<<"FillCorrespondingEdges"<<endl;
411 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
412 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
415 ShapeAnalysis_Edge sae;
416 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
417 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
418 TopTools_MapOfShape Vs1,Vs2;
420 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
423 TopExp_Explorer exp1;
424 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
425 E1 = TopoDS::Edge(exp1.Current());
426 TopoDS_Vertex V1 = sae.FirstVertex(E1);
427 TopoDS_Vertex V2 = sae.LastVertex(E1);
428 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
429 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
430 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
431 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
432 if (P1.Distance(Ptmp1)<tol) {
436 if (P1.Distance(Ptmp2)<tol) {
443 TopoDS_Vertex VE21,VE22;
445 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
446 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
447 TopoDS_Vertex V1 = sae.FirstVertex(E);
448 TopoDS_Vertex V2 = sae.LastVertex(E);
449 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
450 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
451 if (P2.Distance(Ptmp1)<tol) {
463 if (P2.Distance(Ptmp2)<tol) {
477 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
478 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
479 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
480 gp_Vec aDir1(PV21,PE21);
481 gp_Vec aDir2(PV21,PE22);
482 double ang1 = aDir.Angle(aDir1);
483 double ang2 = aDir.Angle(aDir2);
484 if (fabs(ang1)<fabs(ang2)) {
497 // find other pairs for vertexes and edges
498 return FillForOtherEdges(FS1,E1,V21,FF);
501 //=======================================================================
502 //function : FindNextPairOfFaces
503 //purpose : auxilary for CreatePipeForShellSections()
504 //=======================================================================
505 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
506 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
507 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
508 TopTools_IndexedDataMapOfShapeShape& FF,
511 //cout<<"FindNextPairOfFaces"<<endl;
512 TopExp_Explorer anExp;
513 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
514 TopoDS_Shape E1 = anExp.Current();
515 if (!FF.Contains(E1)) {
517 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
519 if (!FF.Contains(E1))
520 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
521 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
522 TopExp_Explorer anExpV;
523 anExpV.Init(E1, TopAbs_VERTEX);
524 TopoDS_Shape V1 = anExpV.Current();
525 if (!FF.Contains(V1)) {
527 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
530 if (!aMapEdgeFaces1.Contains(E1))
531 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
532 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
533 if (aList1.Extent()<2)
535 TopTools_ListIteratorOfListOfShape anIter(aList1);
536 if (anIter.Value().IsEqual(aCurFace)) {
539 TopoDS_Shape F1other = anIter.Value();
540 if (FF.Contains(F1other))
543 if (!FF.Contains(aCurFace))
544 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
545 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
546 if (!aMapEdgeFaces2.Contains(E2))
547 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
548 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
549 if (aList2.Extent()<2) {
551 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
553 TopTools_ListIteratorOfListOfShape anIter2(aList2);
554 if (anIter2.Value().IsEqual(F2)) {
557 TopoDS_Shape F2other = anIter2.Value();
558 FF.Add(F1other,F2other);
560 // add pairs of edges to FF
561 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
564 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
567 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
571 //=======================================================================
572 //function : FindFirstPairFaces
573 //purpose : auxilary for Execute()
574 //=======================================================================
575 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
576 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
577 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
579 //cout<<"FindFirstPairFaces"<<endl;
581 // check if vertexes are sub-shapes of sections
582 gp_Pnt P1 = BRep_Tool::Pnt(V1);
583 gp_Pnt P2 = BRep_Tool::Pnt(V2);
584 TopoDS_Vertex V1new,V2new;
586 double mindist = 1.e10;
587 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
588 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
589 gp_Pnt P = BRep_Tool::Pnt(V);
590 double dist = P1.Distance(P);
597 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
598 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
599 gp_Pnt P = BRep_Tool::Pnt(V);
600 double dist = P2.Distance(P);
607 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
608 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
609 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
610 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
611 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
612 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
614 // replace vertexes if it is needed
615 if (!V1.IsSame(V1new)) {
617 P1 = BRep_Tool::Pnt(V1);
618 MESSAGE (" replace V1");
621 MESSAGE (" not replace V1");
622 if (!V2.IsSame(V2new)) {
624 P2 = BRep_Tool::Pnt(V2);
625 MESSAGE (" replace V2");
628 MESSAGE (" not replace V2");
630 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
631 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
632 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
633 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
635 if (!aMapVertFaces1.Contains(V1))
636 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
637 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
638 TopTools_ListIteratorOfListOfShape anIter1(aList1);
639 FS1 = anIter1.Value();
641 double x1=0., y1=0., z1=0.;
643 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
644 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
645 gp_Pnt P = BRep_Tool::Pnt(V);
651 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
653 TColgp_SequenceOfPnt Ps;
654 TopTools_SequenceOfShape Fs;
655 if (!aMapVertFaces2.Contains(V2))
656 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
657 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
658 TopTools_ListIteratorOfListOfShape anIter2(aList2);
659 for (; anIter2.More(); anIter2.Next()) {
660 TopoDS_Shape F = anIter2.Value();
661 double x2=0., y2=0., z2=0.;
663 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
664 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
665 gp_Pnt P = BRep_Tool::Pnt(V);
671 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
678 double MinAng = M_PI;
680 for (; i<=Fs.Length(); i++) {
681 gp_Vec tmpDir(PM1,Ps(i));
682 double ang = fabs(aDir.Angle(tmpDir));
691 //=======================================================================
692 //function : RemoveFaces
693 //purpose : This function returns theShapeFrom without faces of the shape
694 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
695 // a compound otherwise. Auxilary for CreatePipeWithDifferentSections
697 //=======================================================================
698 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
699 const TopoDS_Shape &theFacesToRm)
701 TopTools_IndexedMapOfShape aMapFaces;
702 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
703 BRep_Builder aBuilder;
704 TopoDS_Shape aResult;
706 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
708 aBuilder.MakeShell(TopoDS::Shell(aResult));
711 aBuilder.MakeCompound(TopoDS::Compound(aResult));
714 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
716 for (; anExp.More(); anExp.Next()) {
717 const TopoDS_Shape &aFace = anExp.Current();
719 if (!aMapFaces.Contains(aFace)) {
720 aBuilder.Add(aResult, aFace);
727 //=======================================================================
728 //function : CreatePipeWithDifferentSections
730 //=======================================================================
731 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
732 (const TopoDS_Wire &theWirePath,
733 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
734 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
735 const Standard_Boolean theWithContact,
736 const Standard_Boolean theWithCorrect,
737 const Standard_Boolean IsBySteps,
738 Handle(TColStd_HArray1OfInteger) *theGroups)
742 TopoDS_Wire aWirePath = theWirePath;
744 Standard_Integer nbBases = theHSeqBases->Length();
745 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
747 if (nbLocs && nbLocs != nbBases) {
748 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
751 TopTools_SequenceOfShape aSeqBases;
752 TopTools_SequenceOfShape aSeqLocs;
753 TopTools_SequenceOfShape aSeqFaces;
754 Standard_Boolean NeedCreateSolid = Standard_False;
756 Standard_Integer i = 1;
757 for (i = 1; i <= nbBases; i++) {
758 if (theHSeqBases->Value(i).IsNull())
761 // Make copy to prevent modifying of base object 0020766 : EDF 1320
762 TopoDS_Shape aShapeBase;
763 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
765 aShapeBase = Copy.Shape();
767 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
769 //if for section was specified face with a few wires then a few
770 // pipes were build and make solid
771 if (aTypeBase == TopAbs_SHELL) {
772 // create wire as boundary contour if shell is no closed
773 // get free boundary shapes
774 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
775 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
776 TopExp_Explorer anExp;
778 Standard_Integer NbWires = 0;
779 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
781 aWire = anExp.Current();
785 Standard_ConstructionError::Raise("Bad shell is used as section ");
787 NeedCreateSolid = Standard_True;
788 aSeqFaces.Append(aShapeBase);
789 aSeqBases.Append(aWire);
791 else if (aTypeBase == TopAbs_FACE) {
792 NeedCreateSolid = Standard_True;
793 //for case one path should be used other type function
794 aSeqFaces.Append(aShapeBase);
795 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
796 for (; aExpW.More(); aExpW.Next()) {
797 TopoDS_Shape aWireProf = aExpW.Current();
798 aSeqBases.Append(aWireProf);
801 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
802 aSeqBases.Append(aShapeBase);
804 else if (aTypeBase == TopAbs_EDGE) {
805 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
806 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
807 aSeqBases.Append(aWireProf);
810 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
811 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
813 aSeqLocs.Append(aShapeLoc);
817 nbLocs = aSeqLocs.Length();
820 TopTools_SequenceOfShape Edges;
822 // we have to check that each location shape is a vertex from
823 // path and update aSeqLocs if it is needed (and possible)
824 TColgp_SequenceOfPnt PLocs;
825 for (i=1; i<=nbLocs; i++) {
826 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
827 PLocs.Append(BRep_Tool::Pnt(V));
829 //TopTools_SequenceOfShape Edges;
830 TopExp_Explorer anExp;
831 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
832 Edges.Append(anExp.Current());
834 int nbEdges = Edges.Length();
835 ShapeAnalysis_Edge sae;
836 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
837 double tol = BRep_Tool::Tolerance(edge);
838 TopoDS_Vertex VF = sae.FirstVertex(edge);
839 gp_Pnt PF = BRep_Tool::Pnt(VF);
840 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
841 if (PF.Distance(PLocs.First()) > tol) {
842 Standard_ConstructionError::Raise
843 ("First location shapes is not coincided with first vertex of aWirePath");
845 aSeqLocs.ChangeValue(1) = VF;
846 edge = TopoDS::Edge(Edges.Last());
847 tol = BRep_Tool::Tolerance(edge);
848 TopoDS_Vertex VL = sae.LastVertex(edge);
849 gp_Pnt PL = BRep_Tool::Pnt(VL);
850 if (PL.Distance(PLocs.Last()) > tol) {
851 Standard_ConstructionError::Raise
852 ("Last location shapes is not coincided with last vertex of aWirePath");
854 aSeqLocs.ChangeValue(nbLocs) = VL;
856 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
857 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
858 tol = BRep_Tool::Tolerance(edge);
859 TopoDS_Vertex V1 = sae.FirstVertex(E);
860 TopoDS_Vertex V2 = sae.LastVertex(E);
861 gp_Pnt P1 = BRep_Tool::Pnt(V1);
862 gp_Pnt P2 = BRep_Tool::Pnt(V2);
863 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
864 aSeqLocs.ChangeValue(jcurr) = V2;
868 // find distance between E and aLocs(jcurr)
870 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
871 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
872 if (PPCurve.NbPoints()>0 &&
873 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
874 double param = PPCurve.Parameter(1);
877 // split current edge
878 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
879 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
884 if (Pfp.Distance(P1)<tol) {
885 B.MakeEdge(E1,tc1,tol);
887 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
888 B.Add(E1,TopoDS::Vertex(tmpV));
889 B.MakeEdge(E2,tc2,tol);
890 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
891 B.Add(E2,TopoDS::Vertex(tmpV));
895 B.MakeEdge(E1,tc2,tol);
896 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
897 B.Add(E1,TopoDS::Vertex(tmpV));
900 B.MakeEdge(E2,tc1,tol);
902 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
903 B.Add(E2,TopoDS::Vertex(tmpV));
908 Edges.InsertAfter(i-1,E1);
909 Edges.InsertAfter(i,E2);
913 if (nbEdges<Edges.Length()) {
914 // one of edges was splitted => we have to update WirePath
918 for (i=1; i<=Edges.Length(); i++) {
919 B.Add(W,TopoDS::Edge(Edges.Value(i)));
925 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
928 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
929 // and corresponding edge indices.
930 Standard_Integer i = 1;
935 for (j = 2; j < aSeqLocs.Length(); j++) {
936 SplitLocNums.Append(j);
937 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
938 aP = BRep_Tool::Pnt(aVert);
940 while (i < Edges.Length()) {
943 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
944 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
945 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
951 if (aP.Distance(aPLast) < aTol) {
952 SplitEdgeNums.Append(i - 1);
958 // check curvature of wire for condition that
959 // max summary angle between directions along
960 // wire path must be < 4*PI. If not - split wire
961 // and seguences of shapes, perform pipe for each
962 // and make sewing after that
967 if ( Edges.Length() > 0 ) {
968 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
971 SumAng = fabs(Vec1.Angle(Vec2));
976 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
977 for (i=2; i<=Edges.Length(); i++) {
978 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
979 double tol = BRep_Tool::Tolerance(edge);
980 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
982 double ang = fabs(Vec1.Angle(Vec2));
986 SplitEdgeNums.Append(i-1);
988 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
989 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
990 gp_Pnt P = BRep_Tool::Pnt(aVert);
991 if (P1.Distance(P) < tol) {
992 SplitLocNums.Append(j);
1003 bool isCreateGroups = (theGroups != NULL);
1005 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1006 TopTools_SequenceOfShape aSeqRes;
1007 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1008 Standard_Integer iGrp;
1009 int nn, num1 = 1, num2 = 1;
1010 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1011 // create wirepath and sequences of shapes
1015 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1016 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1018 num1 = SplitEdgeNums.Value(nn) + 1;
1019 TopTools_SequenceOfShape aTmpSeqBases;
1020 TopTools_SequenceOfShape aTmpSeqLocs;
1021 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1022 aTmpSeqBases.Append(aSeqBases.Value(i));
1023 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1025 num2 = SplitLocNums.Value(nn);
1027 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1028 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1029 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1030 aBuilder.SetDiscreteMode();
1031 Standard_Integer nbShapes = aTmpSeqBases.Length();
1032 for (i=1; i<=nbShapes; i++) {
1033 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1034 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1035 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1037 if (!aBuilder.IsReady()) {
1038 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1041 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1043 if (isDone && NeedCreateSolid && nn == 1) {
1044 // Make solid for the first step.
1045 isDone = aBuilder.MakeSolid();
1049 Standard_ConstructionError::Raise("Pipe construction failure");
1052 TopoDS_Shape resShape = aBuilder.Shape();
1054 if (NeedCreateSolid && nn == 1) {
1055 // Remove top lid from the result.
1056 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1059 aSeqRes.Append(resShape);
1062 if (isCreateGroups) {
1064 TopTools_SequenceOfShape aGroups[5];
1066 if (!DoGroups(aBuilder, aGroups)) {
1067 Standard_ConstructionError::Raise("Generate groups failure");
1070 // Get shapes from all groups.
1071 for (iGrp = 0; iGrp < 5; ++iGrp) {
1072 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1076 // create wirepath and sequences of shapes for last part
1080 for (i=num1; i<=Edges.Length(); i++) {
1081 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1083 TopTools_SequenceOfShape aTmpSeqBases;
1084 TopTools_SequenceOfShape aTmpSeqLocs;
1085 for (i=num2; i<=aSeqLocs.Length(); i++) {
1086 aTmpSeqBases.Append(aSeqBases.Value(i));
1087 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1089 // make pipe for last part
1090 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1091 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1092 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1093 aBuilder.SetDiscreteMode();
1094 Standard_Integer nbShapes = aTmpSeqBases.Length();
1095 for (i=1; i<=nbShapes; i++) {
1096 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1097 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1098 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1100 if (!aBuilder.IsReady()) {
1101 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1104 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1106 if (isDone && NeedCreateSolid) {
1107 isDone = aBuilder.MakeSolid();
1111 Standard_ConstructionError::Raise("Pipe construction failure");
1114 TopoDS_Shape resShape = aBuilder.Shape();
1116 if (NeedCreateSolid) {
1117 // Remove bottom lid from the result.
1118 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1121 aSeqRes.Append(resShape);
1124 if (isCreateGroups) {
1126 TopTools_SequenceOfShape aGroups[5];
1128 if (!DoGroups(aBuilder, aGroups)) {
1129 Standard_ConstructionError::Raise("Generate groups failure");
1132 // Get shapes from all groups.
1133 for (iGrp = 0; iGrp < 5; ++iGrp) {
1134 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1138 // make sewing for result
1139 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1140 aSewing->SetTolerance(Precision::Confusion());
1141 aSewing->SetFaceMode(Standard_True);
1142 aSewing->SetFloatingEdgesMode(Standard_False);
1143 aSewing->SetNonManifoldMode(Standard_False);
1144 for (i=1; i<=aSeqRes.Length(); i++) {
1145 aSewing->Add(aSeqRes.Value(i));
1148 aShape = aSewing->SewedShape();
1150 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1152 BRepBuilderAPI_MakeSolid aMkSolid;
1154 aMkSolid.Add(TopoDS::Shell(aShape));
1156 if (!aMkSolid.IsDone()) {
1157 Standard_ConstructionError::Raise("Can't create solid pipe");
1160 TopoDS_Solid aSolid = aMkSolid.Solid();
1161 BRepClass3d_SolidClassifier aSC(aSolid);
1163 aSC.PerformInfinitePoint(Precision::Confusion());
1165 if (aSC.State() == TopAbs_IN) {
1166 aShape = aSolid.Reversed();
1172 if (isCreateGroups) {
1173 // Replase Group shapes by modified ones.
1174 TopTools_SequenceOfShape aSeqGroups[5];
1177 for (iGrp = 0; iGrp < 5; ++iGrp) {
1179 for (i = 1; i <= aSeqRes.Length(); ++i) {
1180 if (iGrp == GROUP_DOWN && i > 1) {
1181 // For DOWN group we use only the first pipe.
1185 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1186 // For UP group we use only the last pipe.
1190 const TopTools_SequenceOfShape &aShapes =
1191 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1194 // For each sub-shape of pipe
1195 for (j = 1; j <= aShapes.Length(); ++j) {
1196 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1198 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1199 // Use the shape modified by sewing.
1200 const TopoDS_Shape &aModifGrpShape =
1201 aSewing->ModifiedSubShape(aGrpShape);
1203 aSeqGroups[iGrp].Append(aModifGrpShape);
1205 // Use the shape as it is.
1206 aSeqGroups[iGrp].Append(aGrpShape);
1213 TopTools_IndexedMapOfShape anIndices;
1215 TopExp::MapShapes(aShape, anIndices);
1217 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1218 Standard_ConstructionError::Raise("Generate groups failure");
1223 // old implementation without splitting
1224 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1225 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1226 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1227 aBuilder.SetDiscreteMode();
1229 Standard_Integer nbShapes = aSeqBases.Length();
1230 Standard_Integer step = nbShapes/nbBases;
1232 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1233 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1235 Standard_Integer ind =0;
1236 Standard_Real aTolConf = Precision::Confusion();
1237 Standard_Real aTolAng = Precision::Angular();
1239 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1240 TopTools_SequenceOfShape usedBases;
1241 Standard_Integer j = 1;
1242 for (; j <= nbBases; j++) {
1243 ind = i + (j-1)*step;
1244 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1245 usedBases.Append(aWireProf);
1247 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1248 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1249 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1252 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1254 if (!aBuilder.IsReady()) {
1255 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1258 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1260 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1262 if (isDone && NeedCreateSolid) {
1263 isDone = aBuilder.MakeSolid();
1267 Standard_ConstructionError::Raise("Pipe construction failure");
1269 aShape = aBuilder.Shape();
1271 if (isCreateGroups) {
1273 TopTools_SequenceOfShape aSeqGroups[5];
1275 if (!DoGroups(aBuilder, aSeqGroups)) {
1276 Standard_ConstructionError::Raise("Generate groups failure");
1280 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1281 TopTools_IndexedMapOfShape anIndices;
1282 const TopoDS_Shape aResult = aBuilder.Shape();
1284 TopExp::MapShapes(aResult, anIndices);
1286 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1287 Standard_ConstructionError::Raise("Generate groups failure");
1290 aSeqFaces.Append(aShape);
1291 for (j = 1; j <=usedBases.Length(); j++)
1292 aBuilder.Delete(usedBases.Value(j));
1299 //=======================================================================
1300 //function : CreatePipeForShellSections
1301 //purpose : auxilary for Execute()
1302 //=======================================================================
1303 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1304 GEOMImpl_IPipe* aCI)
1309 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1310 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1311 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1312 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1313 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1314 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1315 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1317 Standard_Integer nbBases = aBasesObjs->Length(),
1318 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1319 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1321 if (nbLocs != nbBases) {
1322 if (aCI) delete aCI;
1323 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1325 if (nbSubBases && nbSubBases != nbBases) {
1326 if (aCI) delete aCI;
1327 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1330 TopTools_SequenceOfShape VLocs;
1331 for (i=1; i<=nbBases; i++) {
1332 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1333 if (anItemLoc.IsNull())
1335 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1336 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1337 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1339 VLocs.Append(aShapeLoc);
1341 nbLocs = VLocs.Length();
1342 if (nbLocs != nbBases) {
1343 if (aCI) delete aCI;
1344 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1346 // split wire path by location points
1347 TColgp_SequenceOfPnt PLocs;
1348 for (i=1; i<=nbLocs; i++) {
1349 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1350 PLocs.Append(BRep_Tool::Pnt(V));
1353 TopTools_SequenceOfShape Edges;
1354 TopTools_SequenceOfShape Wires;
1355 ShapeAnalysis_Edge sae;
1358 TopExp_Explorer anExp;
1359 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1360 Edges.Append(anExp.Current());
1362 Standard_Integer Num1 = 0;
1363 Standard_Integer Num2 = 0;
1364 for (i=1; i<=Edges.Length(); i++) {
1365 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1366 double tol = BRep_Tool::Tolerance(E);
1367 TopoDS_Vertex V1 = sae.FirstVertex(E);
1368 TopoDS_Vertex V2 = sae.LastVertex(E);
1369 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1370 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1371 if (P1.Distance(PLocs.First()) < tol) {
1374 if (P2.Distance(PLocs.Last()) < tol) {
1378 if (Num1>0 && Num2>0) {
1381 for (i=Num1; i<=Num2; i++) {
1382 B.Add(W,Edges.Value(i));
1387 Wires.Append(aWirePath);
1391 TopExp_Explorer anExp;
1392 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1393 Edges.Append(anExp.Current());
1395 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1396 double tol = BRep_Tool::Tolerance(edge);
1397 TopoDS_Vertex VF = sae.FirstVertex(edge);
1398 gp_Pnt PF = BRep_Tool::Pnt(VF);
1399 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1400 if (PF.Distance(PLocs.First()) > tol) {
1401 if (aCI) delete aCI;
1402 Standard_ConstructionError::Raise
1403 ("First location shapes is not coincided with first vertex of aWirePath");
1405 VLocs.ChangeValue(1) = VF;
1406 edge = TopoDS::Edge(Edges.Last());
1407 tol = BRep_Tool::Tolerance(edge);
1408 TopoDS_Vertex VL = sae.LastVertex(edge);
1409 gp_Pnt PL = BRep_Tool::Pnt(VL);
1410 if (PL.Distance(PLocs.Last()) > tol) {
1411 if (aCI) delete aCI;
1412 Standard_ConstructionError::Raise
1413 ("Last location shapes is not coincided with last vertex of aWirePath");
1415 VLocs.ChangeValue(nbLocs) = VL;
1417 TopTools_SequenceOfShape tmpEdges;
1418 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1419 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1420 tol = BRep_Tool::Tolerance(E);
1421 TopoDS_Vertex V1 = sae.FirstVertex(E);
1422 TopoDS_Vertex V2 = sae.LastVertex(E);
1423 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1424 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1425 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1426 // make wire from current edge and add created
1430 for (j=1; j<=tmpEdges.Length(); j++)
1431 B.Add(W,tmpEdges.Value(j));
1434 VLocs.ChangeValue(jcurr) = V2;
1439 // find distance between E and aLocs(jcurr)
1441 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1442 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1443 if (PPCurve.NbPoints()>0 &&
1444 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1445 double param = PPCurve.Parameter(1);
1448 // split current edge
1449 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1450 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1454 if (Pfp.Distance(P1)<tol) {
1455 B.MakeEdge(E1,tc1,tol);
1457 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1458 B.Add(E1,TopoDS::Vertex(tmpV));
1459 tmpEdges.Append(E1);
1460 B.MakeEdge(E2,tc2,tol);
1461 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1462 B.Add(E2,TopoDS::Vertex(tmpV));
1466 B.MakeEdge(E1,tc2,tol);
1467 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1468 B.Add(E1,TopoDS::Vertex(tmpV));
1471 tmpEdges.Append(E1);
1472 B.MakeEdge(E2,tc1,tol);
1474 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1475 B.Add(E2,TopoDS::Vertex(tmpV));
1478 // create wire from tmpEdges
1481 for (j=1; j<=tmpEdges.Length(); j++)
1482 B.Add(W,tmpEdges.Value(j));
1487 Edges.InsertAfter(i-1,E1);
1488 Edges.InsertAfter(i,E2);
1495 // create wire from other edges
1498 for (; i<=Edges.Length(); i++)
1499 B.Add(W,Edges.Value(i));
1503 if (Wires.Length() != nbLocs-1) {
1504 if (aCI) delete aCI;
1505 Standard_ConstructionError::Raise
1506 ("One of location shapes is not lied on the path");
1509 TopTools_SequenceOfShape aGroups[5];
1510 TopoDS_Compound aComp;
1511 B.MakeCompound(aComp);
1512 for (i = 1; i < nbBases; i++) {
1513 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1515 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1516 if (anItem1.IsNull())
1518 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1519 if (aRefBase1.IsNull())
1521 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1522 if (aShBase1.IsNull())
1524 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1526 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1527 if (anItem2.IsNull())
1529 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1530 if (aRefBase2.IsNull())
1532 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1533 if (aShBase2.IsNull())
1535 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1537 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1538 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1540 if (aCI) delete aCI;
1541 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1544 bool CreateFewSolids = false;
1546 TopExp_Explorer anExp;
1547 Standard_Integer nbf1 = 0;
1548 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1551 Standard_Integer nbf2 = 0;
1552 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1556 CreateFewSolids = true;
1559 if (!CreateFewSolids) {
1560 // we can create only one solid
1561 TopoDS_Shape aWire1, aWire2;
1563 if (aType1==TopAbs_SHELL) {
1564 // create wire as boundary contour if shell is no closed
1565 // get free boundary shapes
1566 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1567 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1568 //TopExp_Explorer anExp;
1569 Standard_Integer NbWires = 0;
1570 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1572 aWire1 = anExp.Current();
1576 if (aCI) delete aCI;
1577 Standard_ConstructionError::Raise("Bad shell is used as section ");
1580 else { // aType1==TopAbs_FACE
1581 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1582 aWire1 = aExpW.Current();
1585 if (aType2==TopAbs_SHELL) {
1586 // create wire as boundary contour if shell is no closed
1587 // get free boundary shapes
1588 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1589 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1590 //TopExp_Explorer anExp;
1591 Standard_Integer NbWires = 0;
1592 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1594 aWire2 = anExp.Current();
1598 if (aCI) delete aCI;
1599 Standard_ConstructionError::Raise("Bad shell is used as section ");
1602 else { // aType2==TopAbs_FACE
1603 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1604 aWire2 = aExpW.Current();
1606 // make pipe using aWire1 and aWire2
1607 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1608 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1609 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1610 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1611 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1612 aBuilder.SetDiscreteMode();
1613 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1614 aWithContact, aWithCorrect);
1615 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1616 aWithContact, aWithCorrect);
1617 if (!aBuilder.IsReady()) {
1618 if (aCI) delete aCI;
1619 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1622 BuildPipeShell(aBuilder);
1624 TopoDS_Shape aShape = aBuilder.Shape();
1625 TopTools_SequenceOfShape aLocalGroups[5];
1628 if (isGenerateGroups) {
1630 if (!DoGroups(aBuilder, aLocalGroups)) {
1631 if (aCI) delete aCI;
1632 Standard_ConstructionError::Raise("Generate groups failure");
1635 // Clear the groups Down and Up.
1636 aLocalGroups[GROUP_DOWN].Clear();
1637 aLocalGroups[GROUP_UP].Clear();
1640 TopoDS_Shell aShell;
1641 B.MakeShell(aShell);
1642 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1643 B.Add(aShell,anExp.Current());
1645 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1646 B.Add(aShell,anExp.Current());
1648 if (isGenerateGroups && i == 1) {
1649 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1652 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1653 B.Add(aShell,anExp.Current());
1655 if (isGenerateGroups && i == nbBases - 1) {
1656 aLocalGroups[GROUP_UP].Append(anExp.Current());
1659 // make sewing for this shell
1660 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1661 aSewing->SetTolerance(Precision::Confusion());
1662 aSewing->SetFaceMode(Standard_True);
1663 aSewing->SetFloatingEdgesMode(Standard_False);
1664 aSewing->SetNonManifoldMode(Standard_False);
1665 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1666 aSewing->Add(anExp.Current());
1669 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1670 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1671 aShell = TopoDS::Shell(aSewShape);
1672 GProp_GProps aSystem;
1673 BRepGProp::VolumeProperties(aShell, aSystem);
1674 if (aSystem.Mass()<0) {
1677 if (BRep_Tool::IsClosed(aShell)) {
1678 TopoDS_Solid aSolid;
1679 B.MakeSolid(aSolid);
1680 B.Add(aSolid,aShell);
1681 B.Add(aComp,aSolid);
1684 B.Add(aComp,aShell);
1688 B.Add(aComp,aShell);
1691 if (isGenerateGroups) {
1692 Standard_Integer iGrp;
1694 for (iGrp = 0; iGrp < 5; ++iGrp) {
1697 // For each sub-shape of pipe
1698 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1699 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1701 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1702 // Use the shape modified by sewing.
1703 const TopoDS_Shape &aModifGrpShape =
1704 aSewing->ModifiedSubShape(aGrpShape);
1706 aGroups[iGrp].Append(aModifGrpShape);
1708 // Use the shape as it is.
1709 aGroups[iGrp].Append(aGrpShape);
1717 // main block - creation few solids (for each pair of faces)
1718 TopTools_MapOfShape aFaces1,aFaces2;
1719 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1720 aFaces1.Add(anExp.Current());
1722 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1723 aFaces2.Add(anExp.Current());
1725 // creating map of edge faces
1726 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1727 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1728 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1729 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1731 // constuct map face->face
1732 TopTools_IndexedDataMapOfShapeShape FF;
1733 TopoDS_Shape FS1,FS2;
1734 if (nbSubBases==0) {
1735 // find edge the most distant from location point
1736 // (this edge is not shared by two faces)
1737 double maxdist = 0.;
1739 TopoDS_Vertex V11,V21;
1740 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1741 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1742 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1743 if (aList.Extent()>1)
1745 TopExp_Explorer expv;
1746 expv.Init(tmp, TopAbs_VERTEX);
1747 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1749 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1750 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1751 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1752 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1757 TopTools_ListIteratorOfListOfShape anIter(aList);
1758 FS1 = anIter.Value();
1762 // main direction for comparing
1763 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1764 // find corresponding edge from next section
1765 double minang = M_PI;
1766 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1767 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1769 TopoDS_Vertex V12,V22;
1770 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1771 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1772 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1773 if (aList.Extent()>1)
1775 TopExp_Explorer expv;
1776 expv.Init(tmp, TopAbs_VERTEX);
1777 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1779 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1780 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1781 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1782 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1783 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1784 TopoDS_Vertex V1,V2;
1787 V1 = V2tmp; P1 = P2tmp;
1788 V2 = V1tmp; P2 = P1tmp;
1791 V1 = V1tmp; P1 = P1tmp;
1792 V2 = V2tmp; P2 = P2tmp;
1794 gp_Vec Vec1(P11,P1);
1795 gp_Vec Vec2(P21,P2);
1796 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1801 TopTools_ListIteratorOfListOfShape anIter(aList);
1802 FS2 = anIter.Value();
1806 // put all pairs to map FF
1812 // add pairs of edges to FF
1813 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1815 if (aCI) delete aCI;
1816 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1822 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1823 if (anItem.IsNull()) {
1824 if (aCI) delete aCI;
1825 Standard_ConstructionError::Raise("Invalid subbase shape");
1827 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1828 if (aRefBase.IsNull()) {
1829 if (aCI) delete aCI;
1830 Standard_ConstructionError::Raise("Invalid subbase shape");
1832 TopoDS_Shape aSh = aRefBase->GetValue();
1834 if (aCI) delete aCI;
1835 Standard_ConstructionError::Raise("Invalid subbase shape");
1837 if (aSh.ShapeType()!=TopAbs_FACE) {
1838 if (aCI) delete aCI;
1839 Standard_ConstructionError::Raise("Invalid subbase shape");
1844 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1845 if (anItem.IsNull()) {
1846 if (aCI) delete aCI;
1847 Standard_ConstructionError::Raise("Invalid subbase shape");
1849 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1850 if (aRefBase.IsNull()) {
1851 if (aCI) delete aCI;
1852 Standard_ConstructionError::Raise("Invalid subbase shape");
1854 TopoDS_Shape aSh = aRefBase->GetValue();
1856 if (aCI) delete aCI;
1857 Standard_ConstructionError::Raise("Invalid subbase shape");
1859 if (aSh.ShapeType()!=TopAbs_FACE) {
1860 if (aCI) delete aCI;
1861 Standard_ConstructionError::Raise("Invalid subbase shape");
1866 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1867 if (aCI) delete aCI;
1868 Standard_ConstructionError::Raise("Invalid subbase shape");
1873 // add pairs of edges to FF
1874 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1875 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1877 if (aCI) delete aCI;
1878 Standard_ConstructionError::Raise("Can not create correct pipe");
1882 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1884 // make pipe for each pair of faces
1885 for (j=1; j<=FF.Extent(); j++) {
1886 TopoDS_Shape F1 = FF.FindKey(j);
1887 if (F1.ShapeType() != TopAbs_FACE)
1889 TopoDS_Shape F2 = FF.FindFromIndex(j);
1890 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1891 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1892 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1893 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1894 // make pipe using aWire1 and aWire2
1895 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1896 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1897 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1898 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1899 aBuilder.SetDiscreteMode();
1900 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1901 aWithContact, aWithCorrect);
1902 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1903 aWithContact, aWithCorrect);
1904 if (!aBuilder.IsReady()) {
1905 if (aCI) delete aCI;
1906 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1909 BuildPipeShell(aBuilder);
1911 TopoDS_Shape aShape = aBuilder.Shape();
1912 TopTools_SequenceOfShape aLocalGroups[5];
1915 if (isGenerateGroups) {
1917 if (!DoGroups(aBuilder, aLocalGroups)) {
1918 if (aCI) delete aCI;
1919 Standard_ConstructionError::Raise("Generate groups failure");
1922 // Clear the groups Down and Up.
1923 aLocalGroups[GROUP_DOWN].Clear();
1924 aLocalGroups[GROUP_UP].Clear();
1927 aLocalGroups[GROUP_DOWN].Append(F1);
1930 if (i == nbBases - 1) {
1931 aLocalGroups[GROUP_UP].Append(F2);
1935 TopoDS_Shell aShell;
1936 B.MakeShell(aShell);
1937 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1938 B.Add(aShell,anExp.Current());
1943 // make sewing for this shell
1944 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1945 aSewing->SetTolerance(Precision::Confusion());
1946 aSewing->SetFaceMode(Standard_True);
1947 aSewing->SetFloatingEdgesMode(Standard_False);
1948 aSewing->SetNonManifoldMode(Standard_False);
1949 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1950 aSewing->Add(anExp.Current());
1953 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1954 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1955 aShell = TopoDS::Shell(aSewShape);
1956 GProp_GProps aSystem;
1957 BRepGProp::VolumeProperties(aShell, aSystem);
1958 if (aSystem.Mass()<0) {
1959 //cout<<"aSewShape is reversed"<<endl;
1962 if (BRep_Tool::IsClosed(aShell)) {
1963 TopoDS_Solid aSolid;
1964 B.MakeSolid(aSolid);
1965 B.Add(aSolid,aShell);
1966 B.Add(aComp,aSolid);
1969 B.Add(aComp,aShell);
1973 B.Add(aComp,aShell);
1976 if (isGenerateGroups) {
1977 // Replase Group shapes by modified ones.
1978 Standard_Integer iGrp;
1981 for (iGrp = 0; iGrp < 5; ++iGrp) {
1984 // For each sub-shape of pipe
1985 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1986 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1988 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1989 // Use the shape modified by sewing.
1990 const TopoDS_Shape &aModifGrpShape =
1991 aSewing->ModifiedSubShape(aGrpShape);
1993 aGroups[iGrp].Append(aModifGrpShape);
1995 // Use the shape as it is.
1996 aGroups[iGrp].Append(aGrpShape);
2006 if (isGenerateGroups) {
2008 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2009 TopTools_IndexedMapOfShape anIndices;
2011 TopExp::MapShapes(aComp, anIndices);
2013 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2014 if (aCI) delete aCI;
2015 Standard_ConstructionError::Raise("Generate groups failure");
2018 StoreGroups(aCI, aGroupIds);
2024 //=======================================================================
2025 //function : CreatePipeShellsWithoutPath
2026 //purpose : auxilary for Execute()
2027 //=======================================================================
2028 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2030 //cout<<"CreatePipeShellsWithoutPath"<<endl;
2034 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2036 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2037 // vertex for recognition
2038 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2039 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2041 Standard_Integer nbBases = aBasesObjs->Length(),
2042 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2044 if (nbv != nbBases) {
2045 if (aCI) delete aCI;
2046 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2049 TopTools_SequenceOfShape aGroups[5];
2050 TopTools_SequenceOfShape SecVs,Bases;
2051 for (i=1; i<=nbBases; i++) {
2053 Handle(Standard_Transient) anItem = VObjs->Value(i);
2054 if (anItem.IsNull())
2056 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2057 TopoDS_Shape V = aRef->GetValue();
2058 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2062 anItem = aBasesObjs->Value(i);
2063 if (anItem.IsNull())
2065 aRef = Handle(GEOM_Function)::DownCast(anItem);
2066 TopoDS_Shape aSh = aRef->GetValue();
2071 nbv = SecVs.Length();
2072 nbBases = Bases.Length();
2073 if (nbv != nbBases) {
2074 if (aCI) delete aCI;
2075 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2078 TopoDS_Compound aComp;
2079 B.MakeCompound(aComp);
2081 for (i = 1; i < nbBases; i++) {
2082 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2083 TopoDS_Shape aShBase1 = Bases.Value(i);
2084 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2085 TopExp_Explorer anExp;
2086 Standard_Integer nbf1 = 0;
2087 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2090 Standard_Integer nbf2 = 0;
2091 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2094 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
2096 if (aCI) delete aCI;
2097 Standard_ConstructionError::Raise("Different number of faces in the sections");
2100 TopTools_MapOfShape aFaces1,aFaces2;
2101 TopTools_MapOfShape aBndEdges1;
2103 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2104 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2106 if (aFaces1.Add(aBaseFace1)) {
2107 // Get boundary edges.
2108 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2110 for (; anExpE.More(); anExpE.Next()) {
2111 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2113 if (!aBndEdges1.Add(aBaseEdge1)) {
2114 aBndEdges1.Remove(aBaseEdge1);
2119 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2120 aFaces2.Add(anExp.Current());
2123 // creating map of edge faces
2124 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2125 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2126 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2127 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2129 // constuct map face->face (and sub-shapes)
2130 TopTools_IndexedDataMapOfShapeShape FF;
2131 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2132 TopoDS_Shape FS1, FS2;
2133 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2134 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2135 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2138 MESSAGE (" first pair of corresponding faces is found");
2140 // add pairs of edges and vertexes to FF
2141 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2143 if (aCI) delete aCI;
2144 Standard_ConstructionError::Raise("Can not create correct pipe");
2146 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
2148 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2149 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
2151 // make pipe for each pair of faces
2152 // auxilary map vertex->edge for created pipe edges
2153 TopTools_IndexedDataMapOfShapeShape VPE;
2154 ShapeAnalysis_Edge sae;
2155 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
2157 for (j=1; j<=FF.Extent(); j++) {
2158 TopoDS_Shape F1 = FF.FindKey(j);
2159 if (F1.ShapeType() != TopAbs_FACE)
2161 TopoDS_Shape F2 = FF.FindFromIndex(j);
2164 //if (nbff!=3) continue;
2166 MESSAGE (" make pipe for "<<nbff<<" face");
2168 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2169 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2170 Handle(Geom_RectangularTrimmedSurface) RTS =
2171 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2172 S1 = RTS->BasisSurface();
2174 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2175 if (Pln1.IsNull()) {
2176 if (aCI) delete aCI;
2177 Standard_ConstructionError::Raise("Surface from face is not plane");
2179 gp_Vec aDir1(Pln1->Axis().Direction());
2181 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2182 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2183 Handle(Geom_RectangularTrimmedSurface) RTS =
2184 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2185 S2 = RTS->BasisSurface();
2187 Handle(Geom_Plane) Pln2 =
2188 Handle(Geom_Plane)::DownCast(S2);
2189 if (Pln2.IsNull()) {
2190 if (aCI) delete aCI;
2191 Standard_ConstructionError::Raise("Surface from face is not plane");
2193 gp_Vec aDir2(Pln2->Axis().Direction());
2195 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2196 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2198 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2200 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2203 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2204 TopTools_SequenceOfShape aNewFs;
2205 TopTools_SequenceOfShape aLocalGroups[5];
2208 for (; anExpE.More(); anExpE.Next()) {
2209 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2211 if (!FF.Contains(E1))
2212 MESSAGE ("map FF not contains key E1");
2214 if (VPE.Contains(E1)) {
2215 aNewFs.Append(VPE.FindFromKey(E1));
2217 MESSAGE (" using existed face");
2222 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2223 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2224 TopoDS_Vertex V2 = sae.LastVertex(E1);
2225 if (!FF.Contains(V1))
2226 MESSAGE ("map FF not contains key V1");
2227 if (!FF.Contains(V2))
2228 MESSAGE ("map FF not contains key V2");
2229 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2230 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2231 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2232 if (Vtmp.IsSame(V4))
2234 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2235 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2236 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2237 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2240 Handle(Geom_BSplineCurve) C2;
2241 if (VPE.Contains(V2)) {
2242 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2244 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2247 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2248 HAP->SetValue(1,P2);
2249 HAP->SetValue(2,P3);
2250 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2251 anInt.Load(aDir1,aDir2);
2254 B.MakeEdge(E2,C2,1.e-7);
2255 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2256 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2261 Handle(Geom_BSplineCurve) C4;
2262 if (VPE.Contains(V1)) {
2263 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2265 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2268 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2269 HAP->SetValue(1,P1);
2270 HAP->SetValue(2,P4);
2271 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2272 anInt.Load(aDir1,aDir2);
2275 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2276 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2277 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2286 B.Add(W,E4.Reversed());
2291 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2292 //bool IsConicC1 = false;
2293 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2294 // IsConicC1 = true;
2295 // cout<<"C1 - Geom_Conic"<<endl;
2297 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2298 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2301 // double tol = BRep_Tool::Tolerance(E1);
2302 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2303 // C1 = ApxC1.Curve();
2305 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2306 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2307 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2312 Handle(Geom_BSplineCurve) CE1 =
2313 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2314 if (CE1->Degree()<3)
2315 CE1->IncreaseDegree(3);
2316 Handle(Geom_BSplineCurve) CE2 =
2317 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2318 if (CE2->Degree()<3)
2319 CE2->IncreaseDegree(3);
2320 Handle(Geom_BSplineCurve) CE3 =
2321 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2322 if (CE3->Degree()<3)
2323 CE3->IncreaseDegree(3);
2324 Handle(Geom_BSplineCurve) CE4 =
2325 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2326 if (CE4->Degree()<3)
2327 CE4->IncreaseDegree(3);
2329 Handle(Geom_Surface) BS;
2331 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2332 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2336 MESSAGE (" can not create BSplineSurface - create Bezier");
2338 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2339 double fp1,lp1,fp2,lp2;
2340 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2341 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2350 // get points from C1
2351 if (P1.Distance(P1C1)<1.e-6) {
2359 double step = (lp-fp)/(NbP-1);
2360 Points.SetValue(1,1,P1);
2362 for (n1=2; n1<NbP; n1++) {
2366 Points.SetValue(1,n1,P);
2368 Points.SetValue(1,NbP,P2);
2369 // get points from C3
2370 if (P4.Distance(P1C3)<1.e-6) {
2378 step = (lp-fp)/(NbP-1);
2379 Points.SetValue(NbP,1,P4);
2381 for (n1=2; n1<NbP; n1++) {
2385 Points.SetValue(NbP,n1,P);
2387 Points.SetValue(NbP,NbP,P3);
2388 // create isolines and get points from them
2389 for (n1=1; n1<=NbP; n1++) {
2390 gp_Pnt PI1 = Points.Value(1,n1);
2391 gp_Pnt PI2 = Points.Value(NbP,n1);
2392 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2393 HAP->SetValue(1,PI1);
2394 HAP->SetValue(2,PI2);
2395 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2396 anInt.Load(aDir1,aDir2);
2398 Handle(Geom_Curve) iso = anInt.Curve();
2399 fp = iso->FirstParameter();
2400 lp = iso->LastParameter();
2401 step = (lp-fp)/(NbP-1);
2403 TopoDS_Compound VComp;
2404 B.MakeCompound(VComp);
2405 for (n2=2; n2<NbP; n2++) {
2409 Points.SetValue(n2,n1,P);
2412 // create surface and face
2413 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2414 BS = new Geom_BezierSurface(Points);
2417 BRepBuilderAPI_MakeFace BB(BS,W);
2418 TopoDS_Face NewF = BB.Face();
2419 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2421 sff->FixOrientation();
2422 TopoDS_Face FixedFace = sff->Face();
2423 aNewFs.Append(FixedFace);
2424 VPE.Add(E1,FixedFace);
2426 if (isGenerateGroups) {
2427 if (aBndEdges1.Contains(E1)) {
2428 // This is a boundary face.
2429 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2434 TopoDS_Shell aShell;
2435 B.MakeShell(aShell);
2436 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2437 B.Add(aShell,aNewFs(nf));
2443 if (isGenerateGroups && i == 1) {
2444 aLocalGroups[GROUP_DOWN].Append(F1);
2447 if (isGenerateGroups && i == nbBases - 1) {
2448 aLocalGroups[GROUP_UP].Append(F2);
2451 // make sewing for this shell
2452 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2453 aSewing->SetTolerance(Precision::Confusion());
2454 aSewing->SetFaceMode(Standard_True);
2455 aSewing->SetFloatingEdgesMode(Standard_False);
2456 aSewing->SetNonManifoldMode(Standard_False);
2457 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2458 aSewing->Add(anExp.Current());
2461 MESSAGE (" shell for face "<<nbff<<" is created");
2462 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2463 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2464 aShell = TopoDS::Shell(aSewShape);
2465 GProp_GProps aSystem;
2466 BRepGProp::VolumeProperties(aShell, aSystem);
2467 if (aSystem.Mass()<0) {
2468 //cout<<"aSewShape is reversed"<<endl;
2471 if (BRep_Tool::IsClosed(aShell)) {
2472 TopoDS_Solid aSolid;
2473 B.MakeSolid(aSolid);
2474 B.Add(aSolid,aShell);
2475 B.Add(aComp,aSolid);
2476 MESSAGE (" solid for face "<<nbff<<" is created");
2479 B.Add(aComp,aShell);
2480 MESSAGE (" solid for face "<<nbff<<" is not created");
2484 B.Add(aComp,aShell);
2485 MESSAGE (" solid for face "<<nbff<<" is not created");
2488 if (isGenerateGroups) {
2489 Standard_Integer iGrp;
2491 for (iGrp = 0; iGrp < 5; ++iGrp) {
2494 // For each sub-shape of pipe
2495 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2496 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2498 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2499 // Use the shape modified by sewing.
2500 const TopoDS_Shape &aModifGrpShape =
2501 aSewing->ModifiedSubShape(aGrpShape);
2503 aGroups[iGrp].Append(aModifGrpShape);
2505 // Use the shape as it is.
2506 aGroups[iGrp].Append(aGrpShape);
2514 if (isGenerateGroups) {
2516 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2517 TopTools_IndexedMapOfShape anIndices;
2519 TopExp::MapShapes(aComp, anIndices);
2521 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2522 if (aCI) delete aCI;
2523 Standard_ConstructionError::Raise("Generate groups failure");
2526 StoreGroups(aCI, aGroupIds);
2532 //=======================================================================
2533 //function : CreatePipeBiNormalAlongVector
2534 //purpose : auxilary for Execute()
2535 //=======================================================================
2536 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2537 GEOMImpl_IPipe* aCI)
2539 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2541 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2542 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2543 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2544 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2546 if (aShapeBase.IsNull()) {
2547 if (aCIBN) delete aCIBN;
2548 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2551 // Make copy to prevent modifying of base object: 0021525
2552 BRepBuilderAPI_Copy Copy (aShapeBase);
2554 aShapeBase = Copy.Shape();
2557 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2560 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2561 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2563 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2566 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2567 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2568 aProf = wexp.Current();
2571 Standard_TypeMismatch::Raise
2572 ("MakePipe aborted : invalid type of base");
2574 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2575 PipeBuilder.Add(aProf);
2577 if (aShapeVec.IsNull()) {
2578 if (aCIBN) delete aCIBN;
2579 Standard_NullObject::Raise
2580 ("MakePipe aborted : null vector argument");
2582 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2583 Standard_TypeMismatch::Raise
2584 ("MakePipe aborted: invalid type of vector");
2585 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2586 TopoDS_Vertex V1, V2;
2587 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2588 if (V1.IsNull() || V2.IsNull())
2589 Standard_NullObject::Raise
2590 ("MakePipe aborted: vector is not defined");
2591 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2592 gp_Dir BiNormal(aVec);
2593 PipeBuilder.SetMode(BiNormal);
2595 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2597 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2598 PipeBuilder.MakeSolid();
2601 if (!CreateGroups(PipeBuilder, aCIBN)) {
2602 if (aCIBN) delete aCIBN;
2603 Standard_ConstructionError::Raise("Generate groups failure");
2606 return PipeBuilder.Shape();
2609 //=======================================================================
2610 //function : FillGroups
2611 //purpose : auxilary for DoGroups()
2612 //=======================================================================
2613 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2614 const TopTools_IndexedMapOfShape &theIndices,
2615 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2619 for (i = 0; i < 5; ++i) {
2620 if (!theGroups[i].IsEmpty()) {
2621 const Standard_Integer aNbShapes = theGroups[i].Length();
2624 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2626 for (j = 1; j <= aNbShapes; ++j) {
2627 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2628 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2634 theGroupIds[i]->SetValue(j, anIndex);
2642 //=======================================================================
2643 //function : StoreGroups
2644 //purpose : auxilary for CreateGroups()
2645 //=======================================================================
2646 void StoreGroups(GEOMImpl_IPipe *theCI,
2647 Handle(TColStd_HArray1OfInteger) *theGroups)
2649 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2650 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2653 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2654 theCI->SetGroupUp(theGroups[GROUP_UP]);
2657 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2658 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2661 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2662 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2665 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2666 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2670 //=======================================================================
2671 //function : CreateDownUpGroups
2672 //purpose : auxilary for DoGroups()
2673 //=======================================================================
2674 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2675 TopTools_SequenceOfShape *theGroups,
2676 Standard_Boolean &IsDoSides)
2678 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2679 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2680 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2682 IsDoSides = Standard_False;
2687 anUpDownType = TopAbs_EDGE;
2689 if (GEOMUtils::IsOpenPath(aDownShape)) {
2690 IsDoSides = Standard_True;
2695 anUpDownType = TopAbs_FACE;
2701 if (anUpDownType == TopAbs_SHAPE) {
2702 // Invalid Up and Down group type.
2706 TopExp_Explorer anExp(aDownShape, anUpDownType);
2707 TopTools_MapOfShape aMapFence;
2709 // Create Down group.
2710 for (; anExp.More(); anExp.Next()) {
2711 const TopoDS_Shape &aShape = anExp.Current();
2713 if (aMapFence.Add(aShape)) {
2714 theGroups[GROUP_DOWN].Append(aShape);
2719 const TopoDS_Shape anUpShape = theSweep->LastShape();
2722 anExp.Init(anUpShape, anUpDownType);
2724 for (; anExp.More(); anExp.Next()) {
2725 const TopoDS_Shape &aShape = anExp.Current();
2727 if (aMapFence.Add(aShape)) {
2728 theGroups[GROUP_UP].Append(aShape);
2735 //=======================================================================
2736 //function : DoGroups
2737 //purpose : auxilary for CreateGroups()
2738 //=======================================================================
2739 bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2740 TopTools_SequenceOfShape *theGroups)
2742 Standard_Boolean isDoSides = Standard_False;
2744 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2745 // Up and Down groups creation failure
2749 const TopoDS_Shape aDownShape = theSweep.FirstShape();
2752 // Create Side1 and Side2 groups.
2753 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2754 TopoDS_Vertex aV[2];
2757 if (aType == TopAbs_EDGE) {
2758 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2759 } else { // aType == TopAbs_WIRE
2760 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2763 for (i = 0; i < 2; ++i) {
2764 if (aV[i].IsNull() == Standard_False) {
2765 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2767 if (!aLstSide.IsEmpty()) {
2768 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2769 TopTools_MapOfShape aMapFence;
2770 const Standard_Integer anIdSide =
2771 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2773 for (; aSideIt.More(); aSideIt.Next()) {
2774 const TopoDS_Shape &aSideShape = aSideIt.Value();
2776 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2777 if (aMapFence.Add(aSideShape)) {
2778 theGroups[anIdSide].Append(aSideShape);
2781 // Only edges can be is Side1 and Side2 groups.
2789 // Create Other group. Get boudnary edges of the profile.
2790 TopTools_MapOfShape aMapBndEdges;
2791 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2793 for (; anExp.More(); anExp.Next()) {
2794 const TopoDS_Shape &anEdge = anExp.Current();
2796 if (!aMapBndEdges.Add(anEdge)) {
2797 aMapBndEdges.Remove(anEdge);
2801 // Fill the map of faces generated from profile's boundary edges.
2802 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2803 TopTools_MapOfShape aMapFence;
2805 for (; anIter.More(); anIter.Next()) {
2806 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2808 if (!aLstOther.IsEmpty()) {
2809 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2811 for (; anOtherIt.More(); anOtherIt.Next()) {
2812 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2814 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2815 if (aMapFence.Add(anOtherShape)) {
2816 theGroups[GROUP_OTHER].Append(anOtherShape);
2819 // Only faces can be in Other group.
2830 //=======================================================================
2831 //function : CreateGroups
2832 //purpose : auxilary for Execute()
2833 //=======================================================================
2834 bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2835 GEOMImpl_IPipe *theCI)
2837 if (!theCI->GetGenerateGroups()) {
2843 TopTools_SequenceOfShape aGroups[5];
2845 if (!DoGroups(theSweep, aGroups)) {
2850 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2851 TopTools_IndexedMapOfShape anIndices;
2852 const TopoDS_Shape aResult = theSweep.Shape();
2854 TopExp::MapShapes(aResult, anIndices);
2856 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2861 StoreGroups(theCI, aGroupIds);
2866 //=======================================================================
2867 //function : DoGroups
2868 //purpose : auxilary for CreateGroups()
2869 //=======================================================================
2870 static bool DoGroups(const TopoDS_Shape &theProfile,
2871 const TopoDS_Shape &thePath,
2872 BRepOffsetAPI_MakePipe &theSweep,
2873 TopTools_SequenceOfShape *theGroups)
2875 Standard_Boolean isDoSides = Standard_False;
2877 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2878 // Up and Down groups creation failure
2883 // Create Side1 and Side2 groups.
2884 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2885 TopoDS_Vertex aV[2];
2888 if (aType == TopAbs_EDGE) {
2889 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2890 } else { // aType == TopAbs_WIRE
2891 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
2894 for (i = 0; i < 2; ++i) {
2895 if (aV[i].IsNull() == Standard_False) {
2896 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2897 TopTools_MapOfShape aMapFence;
2898 const Standard_Integer anIdSide =
2899 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2901 for (; anExpP.More(); anExpP.Next()) {
2902 const TopoDS_Shape aSideShape =
2903 theSweep.Generated(anExpP.Current(), aV[i]);
2905 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2906 if (aMapFence.Add(aSideShape)) {
2907 theGroups[anIdSide].Append(aSideShape);
2910 // Only edges can be is Side1 and Side2 groups.
2917 // Create Other group. Get boudnary edges of the profile.
2918 TopTools_MapOfShape aMapBndEdges;
2919 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
2921 for (; anExp.More(); anExp.Next()) {
2922 const TopoDS_Shape &anEdge = anExp.Current();
2924 if (!aMapBndEdges.Add(anEdge)) {
2925 aMapBndEdges.Remove(anEdge);
2929 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2930 TopTools_MapOfShape aMapFence;
2932 for (; anExpP.More(); anExpP.Next()) {
2933 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2935 for (; anIter.More(); anIter.Next()) {
2936 const TopoDS_Shape anOtherShape =
2937 theSweep.Generated(anExpP.Current(), anIter.Key());
2939 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2940 if (aMapFence.Add(anOtherShape)) {
2941 theGroups[GROUP_OTHER].Append(anOtherShape);
2944 // Only faces can be in Other group.
2954 //=======================================================================
2955 //function : CreateGroups
2956 //purpose : auxilary for Execute()
2957 //=======================================================================
2958 static bool CreateGroups(const TopoDS_Shape &theProfile,
2959 const TopoDS_Shape &thePath,
2960 BRepOffsetAPI_MakePipe &theSweep,
2961 GEOMImpl_IPipe *theCI)
2963 if (!theCI->GetGenerateGroups()) {
2969 TopTools_SequenceOfShape aGroups[5];
2971 if (!DoGroups(theProfile, thePath, theSweep, aGroups)) {
2976 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2977 TopTools_IndexedMapOfShape anIndices;
2978 const TopoDS_Shape aResult = theSweep.Shape();
2980 TopExp::MapShapes(aResult, anIndices);
2982 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2987 StoreGroups(theCI, aGroupIds);
2992 //=======================================================================
2993 //function : Execute
2995 //=======================================================================
2996 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2998 if (Label().IsNull()) return 0;
2999 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3000 Standard_Integer aType = aFunction->GetType();
3002 GEOMImpl_IPipe* aCI = 0;
3003 if (aType == PIPE_BASE_PATH)
3004 aCI = new GEOMImpl_IPipe (aFunction);
3005 else if (aType == PIPE_DIFFERENT_SECTIONS)
3006 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3007 else if (aType == PIPE_SHELL_SECTIONS)
3008 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3009 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3010 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3011 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3012 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3016 TopoDS_Wire aWirePath;
3017 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3018 // working with path
3019 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3020 TopoDS_Shape aShapePath = aRefPath->GetValue();
3022 if (aShapePath.IsNull()) {
3023 MESSAGE ("Driver : path is null");
3024 if (aCI) delete aCI;
3025 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3030 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3031 TopTools_SequenceOfShape anEdges;
3032 TopExp_Explorer anExp;
3036 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3037 B.Add(W, anExp.Current());
3043 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3044 aWirePath = TopoDS::Wire(aShapePath);
3048 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3049 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3050 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3055 if (aCI) delete aCI;
3056 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3059 // Check if it is possible to create groups.
3060 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3065 Standard_ConstructionError::Raise
3066 ("Can't create groups if the path is closed");
3070 TopoDS_Shape aShape;
3071 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3073 if (aType == PIPE_BASE_PATH) {
3074 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3075 TopoDS_Shape aShapeBase;
3077 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3078 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3080 aShapeBase = Copy.Shape();
3082 if (aShapeBase.IsNull()) {
3083 if (aCI) delete aCI;
3084 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3088 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3089 aShapeBase.ShapeType() == TopAbs_WIRE)
3091 TopoDS_Wire Profile;
3092 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3093 Profile = TopoDS::Wire(aShapeBase);
3097 BB.MakeWire(Profile);
3098 BB.Add(Profile, aShapeBase);
3101 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3102 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3103 if (FaceBuilder.IsDone())
3104 Sweep.SetMode(FaceBuilder.Face());
3107 Standard_Boolean isDone = BuildPipeShell(Sweep);
3111 if (aCI) delete aCI;
3112 Standard_ConstructionError::Raise("MakePipeShell failed");
3115 aShape = Sweep.Shape(); //result is good
3117 if (!CreateGroups(Sweep, aCI)) {
3118 if (aCI) delete aCI;
3119 Standard_ConstructionError::Raise("Generate groups failure");
3124 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3125 BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode);
3127 if (aMkPipe.IsDone()) {
3128 aShape = aMkPipe.Shape();
3130 if (!CreateGroups(aShapeBase, aWirePath, aMkPipe, aCI)) {
3131 if (aCI) delete aCI;
3132 Standard_ConstructionError::Raise("Generate groups failure");
3134 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3135 // Try to use Descrete Trihedron mode.
3136 BRepOffsetAPI_MakePipe aMkPipeDescrete
3137 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron);
3139 if (aMkPipeDescrete.IsDone()) {
3140 aShape = aMkPipeDescrete.Shape();
3142 if (!CreateGroups(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3143 if (aCI) delete aCI;
3144 Standard_ConstructionError::Raise("Generate groups failure");
3151 //building pipe with different sections
3152 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3153 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3154 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3155 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3156 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3157 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3158 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3165 Standard_Integer nbBases = aBasesObjs->Length();
3166 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3168 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3169 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3172 for (i = 1; i <= nbBases; i++) {
3173 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3174 if (anItem.IsNull())
3176 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3177 if (aRefBase.IsNull())
3179 if (aRefBase->GetValue().IsNull())
3182 aHSeqBases->Append(aRefBase->GetValue());
3184 for (i = 1; i <= nbLocs; i++) {
3185 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3186 if (anItemLoc.IsNull())
3188 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3189 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3190 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3193 aHSeqLocs->Append(aShapeLoc);
3197 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3198 Handle(TColStd_HArray1OfInteger) aGroups[5];
3200 if (isGenerateGroups) {
3204 aShape = CreatePipeWithDifferentSections
3205 (aWirePath, aHSeqBases, aHSeqLocs,
3206 aWithContact, aWithCorrect, isBySteps, pGroups);
3208 if (isGenerateGroups) {
3209 // Store created groups.
3210 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3212 StoreGroups(&aPipeDS, aGroups);
3216 //building pipe with shell sections
3217 else if (aType == PIPE_SHELL_SECTIONS) {
3218 aShape = CreatePipeForShellSections(aWirePath,aCI);
3221 //building pipe shell sections without path
3222 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3223 aShape = CreatePipeShellsWithoutPath(aCI);
3226 //building a pipe with constant bi-normal along given vector
3227 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3228 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3236 if (aShape.IsNull()) return 0;
3238 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3239 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3241 if (aType != PIPE_BASE_PATH &&
3242 aType != PIPE_SHELLS_WITHOUT_PATH) {
3243 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3244 if (anExpV.More()) {
3245 Standard_Real aVertMaxTol = -RealLast();
3246 for (; anExpV.More(); anExpV.Next()) {
3247 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3248 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3249 if (aTol > aVertMaxTol)
3252 aVertMaxTol += Precision::Confusion();
3254 TopTools_DataMapOfShapeListOfShape aMapModif;
3255 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3257 if (isGenerateGroups) {
3258 pMapModif = &aMapModif;
3261 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3262 (aShape, aVertMaxTol, Standard_True, pMapModif);
3264 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3266 GEOMImpl_IPipe aCI(aFunction);
3267 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3268 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3269 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3270 TopTools_IndexedMapOfShape anIndices;
3271 TopTools_IndexedMapOfShape aNewIndices;
3272 TopTools_SequenceOfShape aNewShapes[5];
3273 TopTools_MapOfShape aMapReplaced;
3274 TopTools_MapOfShape aMapGlued;
3275 Standard_Integer iGrp;
3278 TopExp::MapShapes(aShape, anIndices);
3279 TopExp::MapShapes(aNewShape, aNewIndices);
3281 for (iGrp = 0; iGrp < 5; ++iGrp) {
3282 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3283 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3284 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3286 for (i = aLower; i <= anUpper; ++i) {
3287 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3288 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3290 if (aMapModif.IsBound(aSubShape)) {
3291 const TopTools_ListOfShape &aListModif =
3292 aMapModif.Find(aSubShape);
3293 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3295 for (; anIter.More(); anIter.Next()) {
3296 const TopoDS_Shape &aNewShape = anIter.Value();
3298 if (aMapReplaced.Add(aNewShape)) {
3299 aNewShapes[iGrp].Append(aNewShape);
3301 // This is a glued shape. It means that it is internal
3302 // one and should be removed from groups later.
3303 aMapGlued.Add(aNewShape);
3307 // Shape is not modified.
3308 aNewShapes[iGrp].Append(aSubShape);
3314 if (!aMapGlued.IsEmpty()) {
3315 // Remove glued (internal) shapes from groups.
3316 for (iGrp = 0; iGrp < 5; ++iGrp) {
3317 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3319 for (i = 1; i < aNbShapes; ++i) {
3320 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3322 if (aMapGlued.Contains(aNewShape)) {
3323 aNewShapes[iGrp].Remove(i);
3331 // Store modified groups.
3332 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3334 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3335 Standard_ConstructionError::Raise("Generate groups failure");
3338 StoreGroups(&aCI, aNewGroupIDs);
3345 // Note: group indices should not be changed after the next call.
3346 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3347 aFunction->SetValue(aRes);
3349 log.SetTouched(Label());
3353 //================================================================================
3355 * \brief Returns a name of creation operation and names and values of creation parameters
3357 //================================================================================
3359 bool GEOMImpl_PipeDriver::
3360 GetCreationInformation(std::string& theOperationName,
3361 std::vector<GEOM_Param>& theParams)
3363 if (Label().IsNull()) return 0;
3364 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3365 Standard_Integer aType = function->GetType();
3368 case PIPE_BASE_PATH:
3370 theOperationName = "PIPE";
3371 GEOMImpl_IPipe aCI( function );
3372 AddParam( theParams, "Base Object", aCI.GetBase() );
3373 AddParam( theParams, "Path Object", aCI.GetPath() );
3376 case PIPE_BI_NORMAL_ALONG_VECTOR:
3378 theOperationName = "PIPE";
3379 GEOMImpl_IPipeBiNormal aCI( function );
3380 AddParam( theParams, "Base Object", aCI.GetBase() );
3381 AddParam( theParams, "Path Object", aCI.GetPath() );
3382 AddParam( theParams, "BiNormal", aCI.GetVector() );
3385 case PIPE_DIFFERENT_SECTIONS:
3387 theOperationName = "PIPE";
3388 GEOMImpl_IPipeDiffSect aCI( function );
3389 AddParam( theParams, "Bases", aCI.GetBases() );
3390 AddParam( theParams, "Locations", aCI.GetLocations() );
3391 AddParam( theParams, "Path", aCI.GetPath() );
3393 if (!aCI.GetIsBySteps()) {
3394 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3395 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3398 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3401 case PIPE_SHELL_SECTIONS:
3403 theOperationName = "PIPE";
3404 GEOMImpl_IPipeShellSect aCI( function );
3405 AddParam( theParams, "Bases", aCI.GetBases() );
3406 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3407 AddParam( theParams, "Locations", aCI.GetLocations() );
3408 AddParam( theParams, "Path", aCI.GetPath() );
3409 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3410 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3413 case PIPE_SHELLS_WITHOUT_PATH:
3415 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3416 GEOMImpl_IPipeShellSect aCI( function );
3417 AddParam( theParams, "Bases", aCI.GetBases() );
3418 AddParam( theParams, "Locations", aCI.GetLocations() );
3428 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
3429 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);