1 // Copyright (C) 2007-2013 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.
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>
41 #include <ShapeFix_Shape.hxx>
42 #include <ShapeFix_ShapeTolerance.hxx>
44 #include <BRep_Tool.hxx>
45 #include <BRep_Builder.hxx>
46 #include <BRepBuilderAPI_Copy.hxx>
47 #include <BRepBuilderAPI_MakeFace.hxx>
48 #include <BRepBuilderAPI_MakeWire.hxx>
49 #include <BRepBuilderAPI_Sewing.hxx>
50 #include <BRepCheck_Analyzer.hxx>
51 #include <BRepGProp.hxx>
52 #include <GeomFill_Trihedron.hxx>
53 #include <GeomFill_CorrectedFrenet.hxx>
54 #include <BRepOffsetAPI_MakePipe.hxx>
55 #include <BRepOffsetAPI_MakePipeShell.hxx>
59 #include <TopExp_Explorer.hxx>
61 #include <TopoDS_Wire.hxx>
62 #include <TopoDS_Edge.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopoDS_Solid.hxx>
65 #include <TopoDS_Shell.hxx>
66 #include <TopoDS_Face.hxx>
67 #include <TopoDS_Compound.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>
74 #include <GProp_GProps.hxx>
76 #include <GeomAPI_ProjectPointOnCurve.hxx>
77 #include <GeomAPI_Interpolate.hxx>
78 #include <Geom_TrimmedCurve.hxx>
79 #include <Geom_Plane.hxx>
80 #include <Geom_RectangularTrimmedSurface.hxx>
81 #include <Geom_BezierSurface.hxx>
82 #include <Geom_Line.hxx>
83 #include <Geom_Conic.hxx>
84 #include <Geom_BSplineCurve.hxx>
85 #include <Geom_BSplineSurface.hxx>
86 #include <GeomAdaptor_HCurve.hxx>
87 #include <GeomFill_BSplineCurves.hxx>
88 #include <GeomConvert_ApproxCurve.hxx>
89 #include <GeomConvert.hxx>
91 #include <TColgp_SequenceOfPnt.hxx>
92 #include <TColgp_HArray1OfPnt.hxx>
93 #include <TColgp_Array2OfPnt.hxx>
94 #include <TColStd_HSequenceOfTransient.hxx>
96 #include <Precision.hxx>
98 #include <Standard_NullObject.hxx>
99 #include <Standard_TypeMismatch.hxx>
100 #include <Standard_ConstructionError.hxx>
102 #include "utilities.h"
105 //=======================================================================
108 //=======================================================================
109 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
111 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
115 //=======================================================================
116 //function : GEOMImpl_PipeDriver
118 //=======================================================================
119 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
123 //=======================================================================
124 //function : EvaluateBestSweepMode
125 //purpose : auxilary for right call of MakePipe and MakePipeShell
126 //=======================================================================
127 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
129 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
131 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
132 for (; Explo.More(); Explo.Next())
134 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
135 Standard_Real fpar, lpar;
136 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
137 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
138 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
140 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
141 aCorrFrenet->SetCurve(GAHcurve);
142 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
143 if (aMode == GeomFill_IsDiscreteTrihedron)
148 if (aMode == GeomFill_IsCorrectedFrenet)
156 //=======================================================================
157 //function : FillForOtherEdges
158 //purpose : auxilary for CreatePipeForShellSections()
159 //=======================================================================
160 static bool FillForOtherEdges(const TopoDS_Shape& F1,
161 const TopoDS_Shape& E1,
162 const TopoDS_Shape& V1,
163 TopTools_IndexedDataMapOfShapeShape& FF)
165 //cout<<"FillForOtherEdges"<<endl;
166 // find other pairs for vertexes and edges
167 // creating map of vertex edges for both faces
168 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
169 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
170 if (!FF.Contains(F1))
171 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
172 if (!FF.Contains(E1))
173 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
174 if (!FF.Contains(V1))
175 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
176 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
177 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
178 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
179 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
180 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
182 TopoDS_Edge ES1 = TopoDS::Edge(E1);
183 TopoDS_Edge ES2 = TopoDS::Edge(E2);
184 TopoDS_Shape VS1 = V1;
185 TopoDS_Shape VS2 = V2;
187 ShapeAnalysis_Edge sae;
189 if (!aMapVertEdge1.Contains(VS1))
190 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
191 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
192 //TopoDS_Shape E1next;
193 TopTools_ListIteratorOfListOfShape anIter1(aList1);
194 if (anIter1.Value().IsSame(ES1)) {
197 //E1next = anIter1.Value();
198 if (!aMapVertEdge2.Contains(VS2))
199 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
200 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
201 //TopoDS_Shape E2next;
202 TopTools_ListIteratorOfListOfShape anIter2(aList2);
203 if (anIter2.Value().IsSame(ES2)) {
206 //E2next = anIter2.Value();
207 //ES1 = TopoDS::Edge(E1next);
208 //ES2 = TopoDS::Edge(E2next);
209 ES1 = TopoDS::Edge(anIter1.Value());
210 ES2 = TopoDS::Edge(anIter2.Value());
211 if (!FF.Contains(ES1)) {
214 if (VS1.IsSame(sae.FirstVertex(ES1)))
215 VS1 = sae.LastVertex(ES1);
217 VS1 = sae.FirstVertex(ES1);
218 if (VS2.IsSame(sae.FirstVertex(ES2)))
219 VS2 = sae.LastVertex(ES2);
221 VS2 = sae.FirstVertex(ES2);
224 if (!FF.Contains(VS1)) {
232 //=======================================================================
233 //function : FillCorrespondingEdges
234 //purpose : auxilary for CreatePipeForShellSections()
235 //=======================================================================
236 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
237 const TopoDS_Shape& FS2,
238 const TopoDS_Vertex& aLoc1,
239 const TopoDS_Vertex& aLoc2,
240 const TopoDS_Wire& aWirePath,
241 TopTools_IndexedDataMapOfShapeShape& FF)
243 //cout<<"FillCorrespondingEdges"<<endl;
244 // find corresponding edges
245 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
246 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
247 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
248 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
249 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
250 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
251 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
252 if (theBestMode == GeomFill_IsDiscreteTrihedron)
253 aBuilder.SetDiscreteMode();
254 aBuilder.Add(aWire1, aLoc1);
255 aBuilder.Add(aWire2, aLoc2);
256 if (!aBuilder.IsReady()) {
260 TopoDS_Shape aShape = aBuilder.Shape();
268 BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
270 ShapeAnalysis_Edge sae;
271 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
272 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
273 TopTools_MapOfShape Vs1,Vs2;
275 exp.Init(FS1, TopAbs_EDGE);
276 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
277 TopoDS_Vertex V11 = sae.FirstVertex(E1);
278 TopoDS_Vertex V21 = sae.LastVertex(E1);
279 gp_Pnt P11 = BRep_Tool::Pnt(V11);
280 gp_Pnt P21 = BRep_Tool::Pnt(V21);
281 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
282 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
283 // find corresponding vertexes from created shape
284 TopoDS_Vertex VN11,VN21;
285 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
286 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
287 gp_Pnt P = BRep_Tool::Pnt(V);
288 if (P.Distance(P11)<tol) {
291 if (P.Distance(P21)<tol) {
295 // find edge contains VN11 and VN21 and corresponding vertexes
296 TopoDS_Vertex VN12,VN22;
297 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
298 TopoDS_Shape F = exp.Current();
299 TopExp_Explorer expe;
301 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
302 TopoDS_Edge E = TopoDS::Edge(expe.Current());
303 TopoDS_Vertex VF = sae.FirstVertex(E);
304 TopoDS_Vertex VL = sae.LastVertex(E);
305 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
311 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
312 TopoDS_Edge E = TopoDS::Edge(expe.Current());
313 TopoDS_Vertex VF = sae.FirstVertex(E);
314 TopoDS_Vertex VL = sae.LastVertex(E);
315 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
317 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
319 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
321 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
327 // find vertexes from FS2 corresponded to VN12 and VN22
328 // and find edge from FS2 contains V12 and V22,
329 // this edge will be corresponded to edge E1
330 TopoDS_Vertex V12,V22;
331 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
332 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
333 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
334 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
336 TopExp_Explorer expe;
337 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
338 TopoDS_Edge E = TopoDS::Edge(expe.Current());
339 TopoDS_Vertex VF = sae.FirstVertex(E);
340 TopoDS_Vertex VL = sae.LastVertex(E);
341 gp_Pnt PF = BRep_Tool::Pnt(VF);
342 gp_Pnt PL = BRep_Tool::Pnt(VL);
343 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
349 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
360 // find other pairs for vertexes and edges
361 // creating map of vertex edges for both faces
362 return FillForOtherEdges(FS1,E1,V21,FF);
367 //=======================================================================
368 //function : FillCorrespondingEdges
369 //purpose : auxilary for CreatePipeShellsWithoutPath()
370 //=======================================================================
371 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
372 const TopoDS_Shape& FS2,
373 const TopoDS_Vertex& aLoc1,
374 const TopoDS_Vertex& aLoc2,
375 TopTools_IndexedDataMapOfShapeShape& FF)
377 //cout<<"FillCorrespondingEdges"<<endl;
379 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
380 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
383 ShapeAnalysis_Edge sae;
384 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
385 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
386 TopTools_MapOfShape Vs1,Vs2;
388 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
391 TopExp_Explorer exp1;
392 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
393 E1 = TopoDS::Edge(exp1.Current());
394 TopoDS_Vertex V1 = sae.FirstVertex(E1);
395 TopoDS_Vertex V2 = sae.LastVertex(E1);
396 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
397 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
398 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
399 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
400 if (P1.Distance(Ptmp1)<tol) {
404 if (P1.Distance(Ptmp2)<tol) {
411 TopoDS_Vertex VE21,VE22;
413 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
414 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
415 TopoDS_Vertex V1 = sae.FirstVertex(E);
416 TopoDS_Vertex V2 = sae.LastVertex(E);
417 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
418 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
419 if (P2.Distance(Ptmp1)<tol) {
431 if (P2.Distance(Ptmp2)<tol) {
445 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
446 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
447 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
448 gp_Vec aDir1(PV21,PE21);
449 gp_Vec aDir2(PV21,PE22);
450 double ang1 = aDir.Angle(aDir1);
451 double ang2 = aDir.Angle(aDir2);
452 if (fabs(ang1)<fabs(ang2)) {
465 // find other pairs for vertexes and edges
466 return FillForOtherEdges(FS1,E1,V21,FF);
469 //=======================================================================
470 //function : FindNextPairOfFaces
471 //purpose : auxilary for CreatePipeForShellSections()
472 //=======================================================================
473 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
474 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
475 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
476 TopTools_IndexedDataMapOfShapeShape& FF,
479 //cout<<"FindNextPairOfFaces"<<endl;
480 TopExp_Explorer anExp;
481 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
482 TopoDS_Shape E1 = anExp.Current();
483 if (!FF.Contains(E1)) {
485 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
487 if (!FF.Contains(E1))
488 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
489 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
490 TopExp_Explorer anExpV;
491 anExpV.Init(E1, TopAbs_VERTEX);
492 TopoDS_Shape V1 = anExpV.Current();
493 if (!FF.Contains(V1)) {
495 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
498 if (!aMapEdgeFaces1.Contains(E1))
499 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
500 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
501 if (aList1.Extent()<2)
503 TopTools_ListIteratorOfListOfShape anIter(aList1);
504 if (anIter.Value().IsEqual(aCurFace)) {
507 TopoDS_Shape F1other = anIter.Value();
508 if (FF.Contains(F1other))
511 if (!FF.Contains(aCurFace))
512 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
513 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
514 if (!aMapEdgeFaces2.Contains(E2))
515 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
516 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
517 if (aList2.Extent()<2) {
519 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
521 TopTools_ListIteratorOfListOfShape anIter2(aList2);
522 if (anIter2.Value().IsEqual(F2)) {
525 TopoDS_Shape F2other = anIter2.Value();
526 FF.Add(F1other,F2other);
528 // add pairs of edges to FF
529 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
532 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
535 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
539 //=======================================================================
540 //function : FindFirstPairFaces
541 //purpose : auxilary for Execute()
542 //=======================================================================
543 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
544 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
545 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
547 //cout<<"FindFirstPairFaces"<<endl;
549 // check if vertexes are sub-shapes of sections
550 gp_Pnt P1 = BRep_Tool::Pnt(V1);
551 gp_Pnt P2 = BRep_Tool::Pnt(V2);
552 TopoDS_Vertex V1new,V2new;
554 double mindist = 1.e10;
555 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
556 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
557 gp_Pnt P = BRep_Tool::Pnt(V);
558 double dist = P1.Distance(P);
565 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
566 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
567 gp_Pnt P = BRep_Tool::Pnt(V);
568 double dist = P2.Distance(P);
575 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
576 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
577 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
578 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
579 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
580 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
582 // replace vertexes if it is needed
583 if (!V1.IsSame(V1new)) {
585 P1 = BRep_Tool::Pnt(V1);
586 MESSAGE (" replace V1");
589 MESSAGE (" not replace V1");
590 if (!V2.IsSame(V2new)) {
592 P2 = BRep_Tool::Pnt(V2);
593 MESSAGE (" replace V2");
596 MESSAGE (" not replace V2");
598 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
599 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
600 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
601 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
603 if (!aMapVertFaces1.Contains(V1))
604 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
605 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
606 TopTools_ListIteratorOfListOfShape anIter1(aList1);
607 FS1 = anIter1.Value();
609 double x1=0., y1=0., z1=0.;
611 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
612 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
613 gp_Pnt P = BRep_Tool::Pnt(V);
619 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
621 TColgp_SequenceOfPnt Ps;
622 TopTools_SequenceOfShape Fs;
623 if (!aMapVertFaces2.Contains(V2))
624 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
625 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
626 TopTools_ListIteratorOfListOfShape anIter2(aList2);
627 for (; anIter2.More(); anIter2.Next()) {
628 TopoDS_Shape F = anIter2.Value();
629 double x2=0., y2=0., z2=0.;
631 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
632 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
633 gp_Pnt P = BRep_Tool::Pnt(V);
639 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
646 double MinAng = M_PI;
648 for (; i<=Fs.Length(); i++) {
649 gp_Vec tmpDir(PM1,Ps(i));
650 double ang = fabs(aDir.Angle(tmpDir));
659 //=======================================================================
660 //function : CreatePipeWithDifferentSections
662 //=======================================================================
663 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
664 (const TopoDS_Wire& theWirePath,
665 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
666 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
667 const Standard_Boolean theWithContact,
668 const Standard_Boolean theWithCorrect)
672 TopoDS_Wire aWirePath = theWirePath;
674 Standard_Integer nbBases = theHSeqBases->Length();
675 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
677 if (nbLocs && nbLocs != nbBases) {
678 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
681 TopTools_SequenceOfShape aSeqBases;
682 TopTools_SequenceOfShape aSeqLocs;
683 TopTools_SequenceOfShape aSeqFaces;
685 Standard_Integer i = 1;
686 for (i = 1; i <= nbBases; i++) {
687 if (theHSeqBases->Value(i).IsNull())
690 // Make copy to prevent modifying of base object 0020766 : EDF 1320
691 TopoDS_Shape aShapeBase;
692 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
694 aShapeBase = Copy.Shape();
696 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
698 //if for section was specified face with a few wires then a few
699 // pipes were build and make solid
700 Standard_Boolean NeedCreateSolid = Standard_False;
701 if (aTypeBase == TopAbs_SHELL) {
702 // create wire as boundary contour if shell is no closed
703 // get free boundary shapes
704 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
705 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
706 TopExp_Explorer anExp;
708 Standard_Integer NbWires = 0;
709 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
711 aWire = anExp.Current();
715 Standard_ConstructionError::Raise("Bad shell is used as section ");
717 NeedCreateSolid = Standard_True;
718 aSeqFaces.Append(aShapeBase);
719 aSeqBases.Append(aWire);
721 else if (aTypeBase == TopAbs_FACE) {
722 NeedCreateSolid = Standard_True;
723 //for case one path should be used other type function
724 aSeqFaces.Append(aShapeBase);
725 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
726 for (; aExpW.More(); aExpW.Next()) {
727 TopoDS_Shape aWireProf = aExpW.Current();
728 aSeqBases.Append(aWireProf);
731 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
732 aSeqBases.Append(aShapeBase);
734 else if (aTypeBase == TopAbs_EDGE) {
735 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
736 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
737 aSeqBases.Append(aWireProf);
740 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
741 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
743 aSeqLocs.Append(aShapeLoc);
747 nbLocs = aSeqLocs.Length();
750 TopTools_SequenceOfShape Edges;
752 // we have to check that each location shape is a vertex from
753 // path and update aSeqLocs if it is needed (and possible)
754 TColgp_SequenceOfPnt PLocs;
755 for (i=1; i<=nbLocs; i++) {
756 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
757 PLocs.Append(BRep_Tool::Pnt(V));
759 //TopTools_SequenceOfShape Edges;
760 TopExp_Explorer anExp;
761 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
762 Edges.Append(anExp.Current());
764 int nbEdges = Edges.Length();
765 ShapeAnalysis_Edge sae;
766 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
767 double tol = BRep_Tool::Tolerance(edge);
768 TopoDS_Vertex VF = sae.FirstVertex(edge);
769 gp_Pnt PF = BRep_Tool::Pnt(VF);
770 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
771 if (PF.Distance(PLocs.First()) > tol) {
772 Standard_ConstructionError::Raise
773 ("First location shapes is not coincided with first vertex of aWirePath");
775 aSeqLocs.ChangeValue(1) = VF;
776 edge = TopoDS::Edge(Edges.Last());
777 tol = BRep_Tool::Tolerance(edge);
778 TopoDS_Vertex VL = sae.LastVertex(edge);
779 gp_Pnt PL = BRep_Tool::Pnt(VL);
780 if (PL.Distance(PLocs.Last()) > tol) {
781 Standard_ConstructionError::Raise
782 ("Last location shapes is not coincided with last vertex of aWirePath");
784 aSeqLocs.ChangeValue(nbLocs) = VL;
786 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
787 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
788 tol = BRep_Tool::Tolerance(edge);
789 TopoDS_Vertex V1 = sae.FirstVertex(E);
790 TopoDS_Vertex V2 = sae.LastVertex(E);
791 gp_Pnt P1 = BRep_Tool::Pnt(V1);
792 gp_Pnt P2 = BRep_Tool::Pnt(V2);
793 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
794 aSeqLocs.ChangeValue(jcurr) = V2;
798 // find distance between E and aLocs(jcurr)
800 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
801 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
802 if (PPCurve.NbPoints()>0 &&
803 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
804 double param = PPCurve.Parameter(1);
807 // split current edge
808 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
809 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
814 if (Pfp.Distance(P1)<tol) {
815 B.MakeEdge(E1,tc1,tol);
817 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
818 B.Add(E1,TopoDS::Vertex(tmpV));
819 B.MakeEdge(E2,tc2,tol);
820 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
821 B.Add(E2,TopoDS::Vertex(tmpV));
825 B.MakeEdge(E1,tc2,tol);
826 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
827 B.Add(E1,TopoDS::Vertex(tmpV));
830 B.MakeEdge(E2,tc1,tol);
832 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
833 B.Add(E2,TopoDS::Vertex(tmpV));
838 Edges.InsertAfter(i-1,E1);
839 Edges.InsertAfter(i,E2);
843 if (nbEdges<Edges.Length()) {
844 // one of edges was splitted => we have to update WirePath
848 for (i=1; i<=Edges.Length(); i++) {
849 B.Add(W,TopoDS::Edge(Edges.Value(i)));
855 // check curvature of wire for condition that
856 // max summary angle between directions along
857 // wire path must be < 4*PI. If not - split wire
858 // and seguences of shapes, perform pipe for each
859 // and make sewing after that
861 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
866 double SumAng = fabs(Vec1.Angle(Vec2));
869 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
871 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
872 for (i=2; i<=Edges.Length(); i++) {
873 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
874 double tol = BRep_Tool::Tolerance(edge);
875 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
877 double ang = fabs(Vec1.Angle(Vec2));
881 SplitEdgeNums.Append(i-1);
883 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
884 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
885 gp_Pnt P = BRep_Tool::Pnt(aVert);
886 if (P1.Distance(P) < tol) {
887 SplitLocNums.Append(j);
897 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
898 TopTools_SequenceOfShape aSeqRes;
899 int nn, num1 = 1, num2 = 1;
900 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
901 // create wirepath and sequences of shapes
905 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
906 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
908 num1 = SplitEdgeNums.Value(nn) + 1;
909 TopTools_SequenceOfShape aTmpSeqBases;
910 TopTools_SequenceOfShape aTmpSeqLocs;
911 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
912 aTmpSeqBases.Append(aSeqBases.Value(i));
913 aTmpSeqLocs.Append(aSeqLocs.Value(i));
915 num2 = SplitLocNums.Value(nn);
917 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
918 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
919 if (theBestMode == GeomFill_IsDiscreteTrihedron)
920 aBuilder.SetDiscreteMode();
921 Standard_Integer nbShapes = aTmpSeqBases.Length();
922 for (i=1; i<=nbShapes; i++) {
923 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
924 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
925 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
927 if (!aBuilder.IsReady()) {
928 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
931 TopoDS_Shape resShape = aBuilder.Shape();
932 aSeqRes.Append(resShape);
934 // create wirepath and sequences of shapes for last part
938 for (i=num1; i<=Edges.Length(); i++) {
939 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
941 TopTools_SequenceOfShape aTmpSeqBases;
942 TopTools_SequenceOfShape aTmpSeqLocs;
943 for (i=num2; i<=aSeqLocs.Length(); i++) {
944 aTmpSeqBases.Append(aSeqBases.Value(i));
945 aTmpSeqLocs.Append(aSeqLocs.Value(i));
947 // make pipe for last part
948 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
949 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
950 if (theBestMode == GeomFill_IsDiscreteTrihedron)
951 aBuilder.SetDiscreteMode();
952 Standard_Integer nbShapes = aTmpSeqBases.Length();
953 for (i=1; i<=nbShapes; i++) {
954 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
955 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
956 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
958 if (!aBuilder.IsReady()) {
959 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
962 TopoDS_Shape resShape = aBuilder.Shape();
963 aSeqRes.Append(resShape);
964 // make sewing for result
965 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
966 aSewing->SetTolerance(Precision::Confusion());
967 aSewing->SetFaceMode(Standard_True);
968 aSewing->SetFloatingEdgesMode(Standard_False);
969 aSewing->SetNonManifoldMode(Standard_False);
970 for (i=1; i<=aSeqRes.Length(); i++) {
971 aSewing->Add(aSeqRes.Value(i));
974 aShape = aSewing->SewedShape();
977 // old implementation without splitting
978 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
979 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
980 if (theBestMode == GeomFill_IsDiscreteTrihedron)
981 aBuilder.SetDiscreteMode();
983 Standard_Integer nbShapes = aSeqBases.Length();
984 Standard_Integer step = nbShapes/nbBases;
986 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
987 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
989 Standard_Integer ind =0;
990 Standard_Real aTolConf = Precision::Confusion();
991 Standard_Real aTolAng = Precision::Angular();
993 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
994 TopTools_SequenceOfShape usedBases;
995 Standard_Integer j = 1;
996 for (; j <= nbBases; j++) {
997 ind = i + (j-1)*step;
998 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
999 usedBases.Append(aWireProf);
1001 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1002 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1003 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1006 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1008 if (!aBuilder.IsReady()) {
1009 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1012 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1015 aShape = aBuilder.Shape();
1016 aSeqFaces.Append(aShape);
1017 for (j = 1; j <=usedBases.Length(); j++)
1018 aBuilder.Delete(usedBases.Value(j));
1021 //for case if section is face
1022 if (aSeqFaces.Length() >1) {
1024 TopoDS_Compound aComp;
1025 aB.MakeCompound(aComp);
1026 for (i = 1; i <= aSeqFaces.Length(); i++)
1027 aB.Add(aComp,aSeqFaces.Value(i));
1035 //=======================================================================
1036 //function : CreatePipeForShellSections
1037 //purpose : auxilary for Execute()
1038 //=======================================================================
1039 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1040 GEOMImpl_IPipe* aCI)
1042 //cout<<"CreatePipeForShellSections"<<endl;
1047 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1048 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1049 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1050 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1051 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1052 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1054 Standard_Integer nbBases = aBasesObjs->Length(),
1055 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1056 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1058 if (nbLocs != nbBases) {
1059 if (aCI) delete aCI;
1060 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1062 if (nbSubBases && nbSubBases != nbBases) {
1063 if (aCI) delete aCI;
1064 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1067 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1069 TopTools_SequenceOfShape VLocs;
1070 for (i=1; i<=nbBases; i++) {
1071 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1072 if (anItemLoc.IsNull())
1074 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1075 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1076 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1078 VLocs.Append(aShapeLoc);
1080 nbLocs = VLocs.Length();
1081 if (nbLocs != nbBases) {
1082 if (aCI) delete aCI;
1083 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1085 // split wire path by location points
1086 TColgp_SequenceOfPnt PLocs;
1087 for (i=1; i<=nbLocs; i++) {
1088 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1089 PLocs.Append(BRep_Tool::Pnt(V));
1092 TopTools_SequenceOfShape Edges;
1093 TopTools_SequenceOfShape Wires;
1094 ShapeAnalysis_Edge sae;
1097 TopExp_Explorer anExp;
1098 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1099 Edges.Append(anExp.Current());
1101 Standard_Integer Num1 = 0;
1102 Standard_Integer Num2 = 0;
1103 for (i=1; i<=Edges.Length(); i++) {
1104 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1105 double tol = BRep_Tool::Tolerance(E);
1106 TopoDS_Vertex V1 = sae.FirstVertex(E);
1107 TopoDS_Vertex V2 = sae.LastVertex(E);
1108 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1109 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1110 if (P1.Distance(PLocs.First()) < tol) {
1113 if (P2.Distance(PLocs.Last()) < tol) {
1117 if (Num1>0 && Num2>0) {
1120 for (i=Num1; i<=Num2; i++) {
1121 B.Add(W,Edges.Value(i));
1126 Wires.Append(aWirePath);
1130 TopExp_Explorer anExp;
1131 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1132 Edges.Append(anExp.Current());
1134 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1135 double tol = BRep_Tool::Tolerance(edge);
1136 TopoDS_Vertex VF = sae.FirstVertex(edge);
1137 gp_Pnt PF = BRep_Tool::Pnt(VF);
1138 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1139 if (PF.Distance(PLocs.First()) > tol) {
1140 if (aCI) delete aCI;
1141 Standard_ConstructionError::Raise
1142 ("First location shapes is not coincided with first vertex of aWirePath");
1144 VLocs.ChangeValue(1) = VF;
1145 edge = TopoDS::Edge(Edges.Last());
1146 tol = BRep_Tool::Tolerance(edge);
1147 TopoDS_Vertex VL = sae.LastVertex(edge);
1148 gp_Pnt PL = BRep_Tool::Pnt(VL);
1149 if (PL.Distance(PLocs.Last()) > tol) {
1150 if (aCI) delete aCI;
1151 Standard_ConstructionError::Raise
1152 ("Last location shapes is not coincided with last vertex of aWirePath");
1154 VLocs.ChangeValue(nbLocs) = VL;
1156 TopTools_SequenceOfShape tmpEdges;
1157 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1158 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1159 tol = BRep_Tool::Tolerance(E);
1160 TopoDS_Vertex V1 = sae.FirstVertex(E);
1161 TopoDS_Vertex V2 = sae.LastVertex(E);
1162 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1163 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1164 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1165 // make wire from current edge and add created
1169 for (j=1; j<=tmpEdges.Length(); j++)
1170 B.Add(W,tmpEdges.Value(j));
1173 VLocs.ChangeValue(jcurr) = V2;
1178 // find distance between E and aLocs(jcurr)
1180 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1181 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1182 if (PPCurve.NbPoints()>0 &&
1183 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1184 double param = PPCurve.Parameter(1);
1187 // split current edge
1188 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1189 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1193 if (Pfp.Distance(P1)<tol) {
1194 B.MakeEdge(E1,tc1,tol);
1196 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1197 B.Add(E1,TopoDS::Vertex(tmpV));
1198 tmpEdges.Append(E1);
1199 B.MakeEdge(E2,tc2,tol);
1200 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1201 B.Add(E2,TopoDS::Vertex(tmpV));
1205 B.MakeEdge(E1,tc2,tol);
1206 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1207 B.Add(E1,TopoDS::Vertex(tmpV));
1210 tmpEdges.Append(E1);
1211 B.MakeEdge(E2,tc1,tol);
1213 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1214 B.Add(E2,TopoDS::Vertex(tmpV));
1217 // create wire from tmpEdges
1220 for (j=1; j<=tmpEdges.Length(); j++)
1221 B.Add(W,tmpEdges.Value(j));
1226 Edges.InsertAfter(i-1,E1);
1227 Edges.InsertAfter(i,E2);
1234 // create wire from other edges
1237 for (; i<=Edges.Length(); i++)
1238 B.Add(W,Edges.Value(i));
1240 //cout<<"Wires.Length()="<<Wires.Length()<<endl;
1243 if (Wires.Length() != nbLocs-1) {
1244 if (aCI) delete aCI;
1245 Standard_ConstructionError::Raise
1246 ("One of location shapes is not lied on the path");
1249 //TopTools_SequenceOfShape aSeqBases;
1250 //TopTools_SequenceOfShape aSeqSubBases;
1251 //TopTools_SequenceOfShape aSeqFaces;
1252 TopoDS_Compound aComp;
1253 B.MakeCompound(aComp);
1254 for (i = 1; i < nbBases; i++) {
1255 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1257 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1258 if (anItem1.IsNull())
1260 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1261 if (aRefBase1.IsNull())
1263 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1264 if (aShBase1.IsNull())
1266 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1268 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1269 if (anItem2.IsNull())
1271 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1272 if (aRefBase2.IsNull())
1274 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1275 if (aShBase2.IsNull())
1277 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1279 //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
1281 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1282 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1284 if (aCI) delete aCI;
1285 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1288 bool CreateFewSolids = false;
1290 TopExp_Explorer anExp;
1291 Standard_Integer nbf1 = 0;
1292 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1295 Standard_Integer nbf2 = 0;
1296 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1300 CreateFewSolids = true;
1304 // check orientation of sections
1305 bool NeedReverse = false;
1308 anExp.Init(aShBase1, TopAbs_FACE);
1309 TopoDS_Shape aFace = anExp.Current();
1310 TColgp_SequenceOfPnt aPnts;
1311 double xc=0, yc=0, zc=0;
1312 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1313 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1314 aPnts.Append(BRep_Tool::Pnt(V));
1315 xc += aPnts.Last().X();
1316 yc += aPnts.Last().Y();
1317 zc += aPnts.Last().Z();
1319 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1320 gp_Vec V1(PC,aPnts.Value(1));
1321 gp_Vec V2(PC,aPnts.Value(2));
1322 gp_Vec VN = V1.Crossed(V2);
1323 for (int ip=2; ip<aPnts.Length(); ip++) {
1324 V1 = gp_Vec(PC,aPnts.Value(ip));
1325 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1326 VN.Add(V1.Crossed(V2));
1329 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
1331 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1332 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1333 double tol = BRep_Tool::Tolerance(edge);
1334 TopoDS_Vertex VF = sae.FirstVertex(edge);
1335 gp_Pnt PF = BRep_Tool::Pnt(VF);
1336 if (PF.Distance(PLoc) < tol) {
1338 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1341 if (P1.Distance(PLoc) < tol) {
1342 C->D0(fp+(lp-fp)/100,P2);
1346 C->D0(lp+(fp-lp)/100,P2);
1348 PathNorm = gp_Vec(P1,P2);
1352 TopoDS_Vertex VL = sae.LastVertex(edge);
1353 gp_Pnt PL = BRep_Tool::Pnt(VL);
1354 if (PL.Distance(PLoc) < tol) {
1356 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1359 if (P1.Distance(PLoc) < tol) {
1360 C->D0(fp+(lp-fp)/100,P2);
1364 C->D0(lp+(fp-lp)/100,P2);
1366 PathNorm = gp_Vec(P2,P1);
1371 cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1372 cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1373 if (fabs(VN.Angle(PathNorm))>PI/2.) {
1380 anExp.Init(aShBase2, TopAbs_FACE);
1381 TopoDS_Shape aFace = anExp.Current();
1382 TColgp_SequenceOfPnt aPnts;
1383 double xc=0, yc=0, zc=0;
1384 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1385 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1386 aPnts.Append(BRep_Tool::Pnt(V));
1387 xc += aPnts.Last().X();
1388 yc += aPnts.Last().Y();
1389 zc += aPnts.Last().Z();
1391 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1392 gp_Vec V1(PC,aPnts.Value(1));
1393 gp_Vec V2(PC,aPnts.Value(2));
1394 gp_Vec VN = V1.Crossed(V2);
1395 for (int ip=2; ip<aPnts.Length(); ip++) {
1396 V1 = gp_Vec(PC,aPnts.Value(ip));
1397 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1398 VN.Add(V1.Crossed(V2));
1401 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
1403 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1404 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1405 double tol = BRep_Tool::Tolerance(edge);
1406 TopoDS_Vertex VF = sae.FirstVertex(edge);
1407 gp_Pnt PF = BRep_Tool::Pnt(VF);
1408 if (PF.Distance(PLoc) < tol) {
1410 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1413 if (P1.Distance(PLoc) < tol) {
1414 C->D0(fp+(lp-fp)/100,P2);
1418 C->D0(lp+(fp-lp)/100,P2);
1420 PathNorm = gp_Vec(P2,P1);
1424 TopoDS_Vertex VL = sae.LastVertex(edge);
1425 gp_Pnt PL = BRep_Tool::Pnt(VL);
1426 if (PL.Distance(PLoc) < tol) {
1428 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1431 if (P1.Distance(PLoc) < tol) {
1432 C->D0(fp+(lp-fp)/100,P2);
1436 C->D0(lp+(fp-lp)/100,P2);
1438 PathNorm = gp_Vec(P2,P1);
1443 //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1444 //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1445 if (fabs(VN.Angle(PathNorm))>PI/2.)
1450 if (!CreateFewSolids) {
1451 // we can create only one solid
1452 TopoDS_Shape aWire1, aWire2;
1454 if (aType1==TopAbs_SHELL) {
1455 // create wire as boundary contour if shell is no closed
1456 // get free boundary shapes
1457 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1458 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1459 //TopExp_Explorer anExp;
1460 Standard_Integer NbWires = 0;
1461 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1463 aWire1 = anExp.Current();
1467 if (aCI) delete aCI;
1468 Standard_ConstructionError::Raise("Bad shell is used as section ");
1471 else { // aType1==TopAbs_FACE
1472 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1473 aWire1 = aExpW.Current();
1476 if (aType2==TopAbs_SHELL) {
1477 // create wire as boundary contour if shell is no closed
1478 // get free boundary shapes
1479 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1480 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1481 //TopExp_Explorer anExp;
1482 Standard_Integer NbWires = 0;
1483 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1485 aWire2 = anExp.Current();
1489 if (aCI) delete aCI;
1490 Standard_ConstructionError::Raise("Bad shell is used as section ");
1493 else { // aType2==TopAbs_FACE
1494 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1495 aWire2 = aExpW.Current();
1497 // make pipe using aWire1 and aWire2
1498 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1499 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1500 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1501 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1502 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1503 aBuilder.SetDiscreteMode();
1504 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1505 aWithContact, aWithCorrect);
1506 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1507 aWithContact, aWithCorrect);
1508 if (!aBuilder.IsReady()) {
1509 if (aCI) delete aCI;
1510 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1513 TopoDS_Shape aShape = aBuilder.Shape();
1514 TopoDS_Shell aShell;
1515 B.MakeShell(aShell);
1516 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1517 B.Add(aShell,anExp.Current());
1519 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1520 B.Add(aShell,anExp.Current());
1522 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1523 B.Add(aShell,anExp.Current());
1525 // make sewing for this shell
1526 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1527 aSewing->SetTolerance(Precision::Confusion());
1528 aSewing->SetFaceMode(Standard_True);
1529 aSewing->SetFloatingEdgesMode(Standard_False);
1530 aSewing->SetNonManifoldMode(Standard_False);
1531 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1532 aSewing->Add(anExp.Current());
1535 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1536 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1537 aShell = TopoDS::Shell(aSewShape);
1538 GProp_GProps aSystem;
1539 BRepGProp::VolumeProperties(aShell, aSystem);
1540 if (aSystem.Mass()<0) {
1543 if (BRep_Tool::IsClosed(aShell)) {
1544 TopoDS_Solid aSolid;
1545 B.MakeSolid(aSolid);
1546 B.Add(aSolid,aShell);
1547 B.Add(aComp,aSolid);
1550 B.Add(aComp,aShell);
1554 B.Add(aComp,aShell);
1559 // main block - creation few solids (for each pair of faces)
1560 TopTools_MapOfShape aFaces1,aFaces2;
1561 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1562 aFaces1.Add(anExp.Current());
1564 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1565 aFaces2.Add(anExp.Current());
1567 // creating map of edge faces
1568 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1569 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1570 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1571 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1573 // constuct map face->face
1574 TopTools_IndexedDataMapOfShapeShape FF;
1575 TopoDS_Shape FS1,FS2;
1576 if (nbSubBases==0) {
1577 // find edge the most distant from location point
1578 // (this edge is not shared by two faces)
1579 double maxdist = 0.;
1581 TopoDS_Vertex V11,V21;
1582 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1583 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1584 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1585 if (aList.Extent()>1)
1587 TopExp_Explorer expv;
1588 expv.Init(tmp, TopAbs_VERTEX);
1589 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1591 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1592 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1593 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1594 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1599 TopTools_ListIteratorOfListOfShape anIter(aList);
1600 FS1 = anIter.Value();
1604 // main direction for comparing
1605 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1606 // find corresponding edge from next section
1607 double minang = M_PI;
1608 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1609 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1611 TopoDS_Vertex V12,V22;
1612 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1613 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1614 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1615 if (aList.Extent()>1)
1617 TopExp_Explorer expv;
1618 expv.Init(tmp, TopAbs_VERTEX);
1619 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1621 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1622 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1623 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1624 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1625 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1626 TopoDS_Vertex V1,V2;
1629 V1 = V2tmp; P1 = P2tmp;
1630 V2 = V1tmp; P2 = P1tmp;
1633 V1 = V1tmp; P1 = P1tmp;
1634 V2 = V2tmp; P2 = P2tmp;
1636 gp_Vec Vec1(P11,P1);
1637 gp_Vec Vec2(P21,P2);
1638 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1643 TopTools_ListIteratorOfListOfShape anIter(aList);
1644 FS2 = anIter.Value();
1648 // put all pairs to map FF
1654 // add pairs of edges to FF
1655 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1657 if (aCI) delete aCI;
1658 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1664 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1665 if (anItem.IsNull()) {
1666 if (aCI) delete aCI;
1667 Standard_ConstructionError::Raise("Invalid subbase shape");
1669 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1670 if (aRefBase.IsNull()) {
1671 if (aCI) delete aCI;
1672 Standard_ConstructionError::Raise("Invalid subbase shape");
1674 TopoDS_Shape aSh = aRefBase->GetValue();
1676 if (aCI) delete aCI;
1677 Standard_ConstructionError::Raise("Invalid subbase shape");
1679 if (aSh.ShapeType()!=TopAbs_FACE) {
1680 if (aCI) delete aCI;
1681 Standard_ConstructionError::Raise("Invalid subbase shape");
1686 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1687 if (anItem.IsNull()) {
1688 if (aCI) delete aCI;
1689 Standard_ConstructionError::Raise("Invalid subbase shape");
1691 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1692 if (aRefBase.IsNull()) {
1693 if (aCI) delete aCI;
1694 Standard_ConstructionError::Raise("Invalid subbase shape");
1696 TopoDS_Shape aSh = aRefBase->GetValue();
1698 if (aCI) delete aCI;
1699 Standard_ConstructionError::Raise("Invalid subbase shape");
1701 if (aSh.ShapeType()!=TopAbs_FACE) {
1702 if (aCI) delete aCI;
1703 Standard_ConstructionError::Raise("Invalid subbase shape");
1708 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1709 if (aCI) delete aCI;
1710 Standard_ConstructionError::Raise("Invalid subbase shape");
1715 // add pairs of edges to FF
1716 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1717 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1719 if (aCI) delete aCI;
1720 Standard_ConstructionError::Raise("Can not create correct pipe");
1724 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1726 // make pipe for each pair of faces
1727 for (j=1; j<=FF.Extent(); j++) {
1728 TopoDS_Shape F1 = FF.FindKey(j);
1729 if (F1.ShapeType() != TopAbs_FACE)
1731 TopoDS_Shape F2 = FF.FindFromIndex(j);
1732 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1733 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1734 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1735 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1736 // make pipe using aWire1 and aWire2
1737 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1738 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1739 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1740 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1741 aBuilder.SetDiscreteMode();
1742 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1743 aWithContact, aWithCorrect);
1744 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1745 aWithContact, aWithCorrect);
1746 if (!aBuilder.IsReady()) {
1747 if (aCI) delete aCI;
1748 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1751 TopoDS_Shape aShape = aBuilder.Shape();
1752 TopoDS_Shell aShell;
1753 B.MakeShell(aShell);
1754 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1755 B.Add(aShell,anExp.Current());
1760 // make sewing for this shell
1761 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1762 aSewing->SetTolerance(Precision::Confusion());
1763 aSewing->SetFaceMode(Standard_True);
1764 aSewing->SetFloatingEdgesMode(Standard_False);
1765 aSewing->SetNonManifoldMode(Standard_False);
1766 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1767 aSewing->Add(anExp.Current());
1770 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1771 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1772 aShell = TopoDS::Shell(aSewShape);
1773 GProp_GProps aSystem;
1774 BRepGProp::VolumeProperties(aShell, aSystem);
1775 if (aSystem.Mass()<0) {
1776 //cout<<"aSewShape is reversed"<<endl;
1779 if (BRep_Tool::IsClosed(aShell)) {
1780 TopoDS_Solid aSolid;
1781 B.MakeSolid(aSolid);
1782 B.Add(aSolid,aShell);
1783 B.Add(aComp,aSolid);
1786 B.Add(aComp,aShell);
1790 B.Add(aComp,aShell);
1798 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
1802 //=======================================================================
1803 //function : CreatePipeShellsWithoutPath
1804 //purpose : auxilary for Execute()
1805 //=======================================================================
1806 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1808 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1812 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1814 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1815 // vertex for recognition
1816 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1818 Standard_Integer nbBases = aBasesObjs->Length(),
1819 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1821 if (nbv != nbBases) {
1822 if (aCI) delete aCI;
1823 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1826 TopTools_SequenceOfShape SecVs,Bases;
1827 for (i=1; i<=nbBases; i++) {
1829 Handle(Standard_Transient) anItem = VObjs->Value(i);
1830 if (anItem.IsNull())
1832 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1833 TopoDS_Shape V = aRef->GetValue();
1834 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1838 anItem = aBasesObjs->Value(i);
1839 if (anItem.IsNull())
1841 aRef = Handle(GEOM_Function)::DownCast(anItem);
1842 TopoDS_Shape aSh = aRef->GetValue();
1847 nbv = SecVs.Length();
1848 nbBases = Bases.Length();
1849 if (nbv != nbBases) {
1850 if (aCI) delete aCI;
1851 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1854 TopoDS_Compound aComp;
1855 B.MakeCompound(aComp);
1857 for (i = 1; i < nbBases; i++) {
1858 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1859 TopoDS_Shape aShBase1 = Bases.Value(i);
1860 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1861 TopExp_Explorer anExp;
1862 Standard_Integer nbf1 = 0;
1863 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1866 Standard_Integer nbf2 = 0;
1867 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1870 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1872 if (aCI) delete aCI;
1873 Standard_ConstructionError::Raise("Different number of faces in the sections");
1876 TopTools_MapOfShape aFaces1,aFaces2;
1877 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1878 aFaces1.Add(anExp.Current());
1880 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1881 aFaces2.Add(anExp.Current());
1884 // creating map of edge faces
1885 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1886 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1887 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1888 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1890 // constuct map face->face (and sub-shapes)
1891 TopTools_IndexedDataMapOfShapeShape FF;
1892 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
1893 TopoDS_Shape FS1, FS2;
1894 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
1895 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
1896 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
1899 MESSAGE (" first pair of corresponding faces is found");
1901 // add pairs of edges and vertexes to FF
1902 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
1904 if (aCI) delete aCI;
1905 Standard_ConstructionError::Raise("Can not create correct pipe");
1907 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
1909 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1910 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
1912 // make pipe for each pair of faces
1913 // auxilary map vertex->edge for created pipe edges
1914 TopTools_IndexedDataMapOfShapeShape VPE;
1915 ShapeAnalysis_Edge sae;
1916 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
1918 for (j=1; j<=FF.Extent(); j++) {
1919 TopoDS_Shape F1 = FF.FindKey(j);
1920 if (F1.ShapeType() != TopAbs_FACE)
1922 TopoDS_Shape F2 = FF.FindFromIndex(j);
1925 //if (nbff!=3) continue;
1927 MESSAGE (" make pipe for "<<nbff<<" face");
1929 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
1930 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1931 Handle(Geom_RectangularTrimmedSurface) RTS =
1932 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
1933 S1 = RTS->BasisSurface();
1935 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
1936 if (Pln1.IsNull()) {
1937 if (aCI) delete aCI;
1938 Standard_ConstructionError::Raise("Surface from face is not plane");
1940 gp_Vec aDir1(Pln1->Axis().Direction());
1942 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
1943 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1944 Handle(Geom_RectangularTrimmedSurface) RTS =
1945 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
1946 S2 = RTS->BasisSurface();
1948 Handle(Geom_Plane) Pln2 =
1949 Handle(Geom_Plane)::DownCast(S2);
1950 if (Pln2.IsNull()) {
1951 if (aCI) delete aCI;
1952 Standard_ConstructionError::Raise("Surface from face is not plane");
1954 gp_Vec aDir2(Pln2->Axis().Direction());
1956 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
1957 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
1959 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
1961 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
1964 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
1965 TopTools_SequenceOfShape aNewFs;
1967 for (; anExpE.More(); anExpE.Next()) {
1968 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
1970 if (!FF.Contains(E1))
1971 MESSAGE ("map FF not contains key E1");
1973 if (VPE.Contains(E1)) {
1974 aNewFs.Append(VPE.FindFromKey(E1));
1976 MESSAGE (" using existed face");
1981 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
1982 TopoDS_Vertex V1 = sae.FirstVertex(E1);
1983 TopoDS_Vertex V2 = sae.LastVertex(E1);
1984 if (!FF.Contains(V1))
1985 MESSAGE ("map FF not contains key V1");
1986 if (!FF.Contains(V2))
1987 MESSAGE ("map FF not contains key V2");
1988 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
1989 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
1990 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
1991 if (Vtmp.IsSame(V4))
1993 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1994 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1995 gp_Pnt P3 = BRep_Tool::Pnt(V3);
1996 gp_Pnt P4 = BRep_Tool::Pnt(V4);
1999 Handle(Geom_BSplineCurve) C2;
2000 if (VPE.Contains(V2)) {
2001 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2003 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2006 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2007 HAP->SetValue(1,P2);
2008 HAP->SetValue(2,P3);
2009 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2010 anInt.Load(aDir1,aDir2);
2013 B.MakeEdge(E2,C2,1.e-7);
2014 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2015 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2020 Handle(Geom_BSplineCurve) C4;
2021 if (VPE.Contains(V1)) {
2022 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2024 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2027 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2028 HAP->SetValue(1,P1);
2029 HAP->SetValue(2,P4);
2030 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2031 anInt.Load(aDir1,aDir2);
2034 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2035 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2036 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2045 B.Add(W,E4.Reversed());
2046 //cout<<" wire for edge "<<nbee<<" is created"<<endl;
2047 //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
2052 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2053 //bool IsConicC1 = false;
2054 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2055 // IsConicC1 = true;
2056 // cout<<"C1 - Geom_Conic"<<endl;
2058 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2059 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2062 // double tol = BRep_Tool::Tolerance(E1);
2063 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2064 // C1 = ApxC1.Curve();
2066 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2067 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2068 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2073 Handle(Geom_BSplineCurve) CE1 =
2074 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2075 if (CE1->Degree()<3)
2076 CE1->IncreaseDegree(3);
2077 Handle(Geom_BSplineCurve) CE2 =
2078 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2079 if (CE2->Degree()<3)
2080 CE2->IncreaseDegree(3);
2081 Handle(Geom_BSplineCurve) CE3 =
2082 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2083 if (CE3->Degree()<3)
2084 CE3->IncreaseDegree(3);
2085 Handle(Geom_BSplineCurve) CE4 =
2086 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2087 if (CE4->Degree()<3)
2088 CE4->IncreaseDegree(3);
2089 //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
2090 // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
2091 //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
2092 // os<<"DrawTrSurf_BSplineCurve"<<endl;
2093 // GeomTools::Write(CE1,os);
2097 Handle(Geom_Surface) BS;
2099 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2100 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2104 MESSAGE (" can not create BSplineSurface - create Bezier");
2106 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2107 double fp1,lp1,fp2,lp2;
2108 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2109 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2118 // get points from C1
2119 if (P1.Distance(P1C1)<1.e-6) {
2127 double step = (lp-fp)/(NbP-1);
2128 Points.SetValue(1,1,P1);
2130 for (n1=2; n1<NbP; n1++) {
2134 Points.SetValue(1,n1,P);
2136 Points.SetValue(1,NbP,P2);
2137 // get points from C3
2138 if (P4.Distance(P1C3)<1.e-6) {
2146 step = (lp-fp)/(NbP-1);
2147 Points.SetValue(NbP,1,P4);
2149 for (n1=2; n1<NbP; n1++) {
2153 Points.SetValue(NbP,n1,P);
2155 Points.SetValue(NbP,NbP,P3);
2156 // create isolines and get points from them
2157 for (n1=1; n1<=NbP; n1++) {
2158 gp_Pnt PI1 = Points.Value(1,n1);
2159 gp_Pnt PI2 = Points.Value(NbP,n1);
2160 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2161 HAP->SetValue(1,PI1);
2162 HAP->SetValue(2,PI2);
2163 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2164 anInt.Load(aDir1,aDir2);
2166 Handle(Geom_Curve) iso = anInt.Curve();
2167 fp = iso->FirstParameter();
2168 lp = iso->LastParameter();
2169 step = (lp-fp)/(NbP-1);
2171 TopoDS_Compound VComp;
2172 B.MakeCompound(VComp);
2173 for (n2=2; n2<NbP; n2++) {
2177 Points.SetValue(n2,n1,P);
2180 // create surface and face
2181 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2182 BS = new Geom_BezierSurface(Points);
2185 BRepBuilderAPI_MakeFace BB(BS,W);
2186 TopoDS_Face NewF = BB.Face();
2187 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2189 sff->FixOrientation();
2190 TopoDS_Face FixedFace = sff->Face();
2191 aNewFs.Append(FixedFace);
2192 VPE.Add(E1,FixedFace);
2193 //cout<<" face for edge "<<nbee<<" is created"<<endl;
2194 //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
2197 TopoDS_Shell aShell;
2198 B.MakeShell(aShell);
2199 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2200 B.Add(aShell,aNewFs(nf));
2205 // make sewing for this shell
2206 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2207 aSewing->SetTolerance(Precision::Confusion());
2208 aSewing->SetFaceMode(Standard_True);
2209 aSewing->SetFloatingEdgesMode(Standard_False);
2210 aSewing->SetNonManifoldMode(Standard_False);
2211 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2212 aSewing->Add(anExp.Current());
2215 MESSAGE (" shell for face "<<nbff<<" is created");
2216 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2217 //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
2218 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2219 aShell = TopoDS::Shell(aSewShape);
2220 GProp_GProps aSystem;
2221 BRepGProp::VolumeProperties(aShell, aSystem);
2222 if (aSystem.Mass()<0) {
2223 //cout<<"aSewShape is reversed"<<endl;
2226 if (BRep_Tool::IsClosed(aShell)) {
2227 TopoDS_Solid aSolid;
2228 B.MakeSolid(aSolid);
2229 B.Add(aSolid,aShell);
2230 B.Add(aComp,aSolid);
2231 MESSAGE (" solid for face "<<nbff<<" is created");
2234 B.Add(aComp,aShell);
2235 MESSAGE (" solid for face "<<nbff<<" is not created");
2239 B.Add(aComp,aShell);
2240 MESSAGE (" solid for face "<<nbff<<" is not created");
2242 //cout<<" solid for face "<<nbff<<" is created"<<endl;
2244 //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
2246 //TopoDS_Shell FixedShell = sfs->Shell();
2248 GProp_GProps aSystem;
2249 BRepGProp::VolumeProperties(FixedShell, aSystem);
2250 if (aSystem.Mass()<0) {
2251 //cout<<"aSewShape is reversed"<<endl;
2252 FixedShell.Reverse();
2254 if (BRep_Tool::IsClosed(FixedShell)) {
2255 TopoDS_Solid aSolid;
2256 B.MakeSolid(aSolid);
2257 B.Add(aSolid,aShell);
2258 B.Add(aComp,aSolid);
2261 B.Add(aComp,FixedShell);
2267 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
2271 //=======================================================================
2272 //function : CreatePipeBiNormalAlongVector
2273 //purpose : auxilary for Execute()
2274 //=======================================================================
2275 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2276 GEOMImpl_IPipe* aCI)
2278 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2280 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2281 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2282 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2283 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2285 if (aShapeBase.IsNull()) {
2286 if (aCIBN) delete aCIBN;
2287 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2290 // Make copy to prevent modifying of base object: 0021525
2291 BRepBuilderAPI_Copy Copy (aShapeBase);
2293 aShapeBase = Copy.Shape();
2296 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2299 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2300 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2302 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2305 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2306 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2307 aProf = wexp.Current();
2310 Standard_TypeMismatch::Raise
2311 ("MakePipe aborted : invalid type of base");
2313 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2314 PipeBuilder.Add(aProf);
2316 if (aShapeVec.IsNull()) {
2317 if (aCIBN) delete aCIBN;
2318 Standard_NullObject::Raise
2319 ("MakePipe aborted : null vector argument");
2321 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2322 Standard_TypeMismatch::Raise
2323 ("MakePipe aborted: invalid type of vector");
2324 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2325 TopoDS_Vertex V1, V2;
2326 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2327 if (V1.IsNull() || V2.IsNull())
2328 Standard_NullObject::Raise
2329 ("MakePipe aborted: vector is not defined");
2330 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2331 gp_Dir BiNormal(aVec);
2332 PipeBuilder.SetMode(BiNormal);
2333 PipeBuilder.Build();
2334 if (aShapeBase.ShapeType() == TopAbs_FACE) {
2335 PipeBuilder.MakeSolid();
2338 return PipeBuilder.Shape();
2341 //=======================================================================
2342 //function : Execute
2344 //=======================================================================
2345 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2347 if (Label().IsNull()) return 0;
2348 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2349 Standard_Integer aType = aFunction->GetType();
2351 GEOMImpl_IPipe* aCI = 0;
2352 if (aType == PIPE_BASE_PATH)
2353 aCI = new GEOMImpl_IPipe (aFunction);
2354 else if (aType == PIPE_DIFFERENT_SECTIONS)
2355 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
2356 else if (aType == PIPE_SHELL_SECTIONS)
2357 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2358 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2359 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2360 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2361 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
2365 TopoDS_Wire aWirePath;
2366 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2367 // working with path
2368 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2369 TopoDS_Shape aShapePath = aRefPath->GetValue();
2371 if (aShapePath.IsNull()) {
2372 MESSAGE ("Driver : path is null");
2373 if (aCI) delete aCI;
2374 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2379 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2380 TopTools_SequenceOfShape anEdges;
2381 TopExp_Explorer anExp;
2385 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2386 B.Add(W, anExp.Current());
2392 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2393 aWirePath = TopoDS::Wire(aShapePath);
2397 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2398 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2399 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2404 if (aCI) delete aCI;
2405 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2409 TopoDS_Shape aShape;
2411 if (aType == PIPE_BASE_PATH) {
2412 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2413 TopoDS_Shape aShapeBase;
2415 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2416 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2418 aShapeBase = Copy.Shape();
2420 if (aShapeBase.IsNull()) {
2421 if (aCI) delete aCI;
2422 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2426 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
2427 aShapeBase.ShapeType() == TopAbs_WIRE)
2429 TopoDS_Wire Profile;
2430 if (aShapeBase.ShapeType() == TopAbs_WIRE)
2431 Profile = TopoDS::Wire(aShapeBase);
2435 BB.MakeWire(Profile);
2436 BB.Add(Profile, aShapeBase);
2439 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
2440 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
2441 if (FaceBuilder.IsDone())
2442 Sweep.SetMode(FaceBuilder.Face());
2446 if (!Sweep.IsDone())
2448 if (aCI) delete aCI;
2449 Standard_ConstructionError::Raise("MakePipeShell failed");
2452 aShape = Sweep.Shape(); //result is good
2457 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
2458 aShape = BRepOffsetAPI_MakePipe(aWirePath, aShapeBase, theBestMode);
2462 //building pipe with different sections
2463 else if (aType == PIPE_DIFFERENT_SECTIONS) {
2464 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
2465 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
2466 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
2467 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
2468 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
2474 Standard_Integer nbBases = aBasesObjs->Length();
2475 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
2477 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
2478 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
2481 for (i = 1; i <= nbBases; i++) {
2482 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
2483 if (anItem.IsNull())
2485 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
2486 if (aRefBase.IsNull())
2488 if (aRefBase->GetValue().IsNull())
2491 aHSeqBases->Append(aRefBase->GetValue());
2493 for (i = 1; i <= nbLocs; i++) {
2494 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
2495 if (anItemLoc.IsNull())
2497 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
2498 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
2499 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
2502 aHSeqLocs->Append(aShapeLoc);
2505 aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
2508 //building pipe with shell sections
2509 else if (aType == PIPE_SHELL_SECTIONS) {
2510 aShape = CreatePipeForShellSections(aWirePath,aCI);
2513 //building pipe shell sections without path
2514 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
2515 aShape = CreatePipeShellsWithoutPath(aCI);
2518 //building a pipe with constant bi-normal along given vector
2519 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
2520 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
2528 if (aShape.IsNull()) return 0;
2530 BRepCheck_Analyzer ana (aShape, Standard_False);
2531 if (!ana.IsValid()) {
2532 ShapeFix_ShapeTolerance aSFT;
2533 aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
2534 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
2535 aSfs->SetPrecision(Precision::Confusion());
2537 aShape = aSfs->Shape();
2539 ana.Init(aShape, Standard_False);
2541 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
2544 if (aType != PIPE_BASE_PATH &&
2545 aType != PIPE_SHELLS_WITHOUT_PATH) {
2546 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
2547 if (anExpV.More()) {
2548 Standard_Real aVertMaxTol = -RealLast();
2549 for (; anExpV.More(); anExpV.Next()) {
2550 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
2551 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
2552 if (aTol > aVertMaxTol)
2555 aVertMaxTol += Precision::Confusion();
2556 aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
2557 //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
2561 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
2562 aFunction->SetValue(aRes);
2564 log.SetTouched(Label());
2568 //================================================================================
2570 * \brief Returns a name of creation operation and names and values of creation parameters
2572 //================================================================================
2574 bool GEOMImpl_PipeDriver::
2575 GetCreationInformation(std::string& theOperationName,
2576 std::vector<GEOM_Param>& theParams)
2578 if (Label().IsNull()) return 0;
2579 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
2580 Standard_Integer aType = function->GetType();
2583 case PIPE_BASE_PATH:
2585 theOperationName = "PIPE";
2586 GEOMImpl_IPipe aCI( function );
2587 AddParam( theParams, "Base Object", aCI.GetBase() );
2588 AddParam( theParams, "Path Object", aCI.GetPath() );
2591 case PIPE_BI_NORMAL_ALONG_VECTOR:
2593 theOperationName = "PIPE";
2594 GEOMImpl_IPipeBiNormal aCI( function );
2595 AddParam( theParams, "Base Object", aCI.GetBase() );
2596 AddParam( theParams, "Path Object", aCI.GetPath() );
2597 AddParam( theParams, "BiNormal", aCI.GetVector() );
2600 case PIPE_DIFFERENT_SECTIONS:
2602 theOperationName = "PIPE";
2603 GEOMImpl_IPipeDiffSect aCI( function );
2604 AddParam( theParams, "Bases", aCI.GetBases() );
2605 AddParam( theParams, "Locations", aCI.GetLocations() );
2606 AddParam( theParams, "Path", aCI.GetPath() );
2607 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2608 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2611 case PIPE_SHELL_SECTIONS:
2613 theOperationName = "PIPE";
2614 GEOMImpl_IPipeShellSect aCI( function );
2615 AddParam( theParams, "Bases", aCI.GetBases() );
2616 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
2617 AddParam( theParams, "Locations", aCI.GetLocations() );
2618 AddParam( theParams, "Path", aCI.GetPath() );
2619 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2620 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2623 case PIPE_SHELLS_WITHOUT_PATH:
2625 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
2626 GEOMImpl_IPipeShellSect aCI( function );
2627 AddParam( theParams, "Bases", aCI.GetBases() );
2628 AddParam( theParams, "Locations", aCI.GetLocations() );
2638 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
2639 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);