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_MakeWire.hxx>
47 #include <BRepBuilderAPI_Sewing.hxx>
48 #include <BRepGProp.hxx>
49 #include <GeomFill_Trihedron.hxx>
50 #include <GeomFill_CorrectedFrenet.hxx>
51 #include <BRepOffsetAPI_MakePipe.hxx>
52 #include <BRepOffsetAPI_MakePipeShell.hxx>
56 #include <TopExp_Explorer.hxx>
58 #include <TopoDS_Wire.hxx>
59 #include <TopoDS_Edge.hxx>
60 #include <TopoDS_Shape.hxx>
61 #include <TopoDS_Solid.hxx>
62 #include <TopoDS_Shell.hxx>
63 #include <TopoDS_Face.hxx>
64 #include <TopoDS_Compound.hxx>
65 #include <TopTools_SequenceOfShape.hxx>
66 #include <TopTools_HSequenceOfShape.hxx>
67 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
68 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
69 #include <TopTools_ListIteratorOfListOfShape.hxx>
71 #include <GProp_GProps.hxx>
73 #include <GeomAPI_ProjectPointOnCurve.hxx>
74 #include <GeomAPI_Interpolate.hxx>
75 #include <Geom_TrimmedCurve.hxx>
76 #include <Geom_Plane.hxx>
77 #include <Geom_RectangularTrimmedSurface.hxx>
78 #include <Geom_BezierSurface.hxx>
79 #include <Geom_Line.hxx>
80 #include <Geom_Conic.hxx>
81 #include <Geom_BSplineCurve.hxx>
82 #include <Geom_BSplineSurface.hxx>
83 #include <GeomAdaptor_HCurve.hxx>
84 #include <GeomFill_BSplineCurves.hxx>
85 #include <GeomConvert_ApproxCurve.hxx>
86 #include <GeomConvert.hxx>
88 #include <TColgp_SequenceOfPnt.hxx>
89 #include <TColgp_HArray1OfPnt.hxx>
90 #include <TColgp_Array2OfPnt.hxx>
91 #include <TColStd_HSequenceOfTransient.hxx>
93 #include <Precision.hxx>
95 #include <Standard_NullObject.hxx>
96 #include <Standard_TypeMismatch.hxx>
97 #include <Standard_ConstructionError.hxx>
99 #include "utilities.h"
102 //=======================================================================
105 //=======================================================================
106 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
108 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
112 //=======================================================================
113 //function : GEOMImpl_PipeDriver
115 //=======================================================================
116 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
120 //=======================================================================
121 //function : EvaluateBestSweepMode
122 //purpose : auxilary for right call of MakePipe and MakePipeShell
123 //=======================================================================
124 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
126 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
128 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
129 for (; Explo.More(); Explo.Next())
131 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
132 Standard_Real fpar, lpar;
133 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
134 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
135 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
137 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
138 aCorrFrenet->SetCurve(GAHcurve);
139 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
140 if (aMode == GeomFill_IsDiscreteTrihedron)
145 if (aMode == GeomFill_IsCorrectedFrenet)
152 //=======================================================================
153 //function : BuildPipeShell
154 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
155 // mode. Returns Standard_True if the building is done successfully.
156 //=======================================================================
157 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
161 Standard_Boolean isDone = theBuilder.IsDone();
164 // Try to use Descrete Trihedron mode.
165 theBuilder.SetDiscreteMode();
167 isDone = theBuilder.IsDone();
173 //=======================================================================
174 //function : FillForOtherEdges
175 //purpose : auxilary for CreatePipeForShellSections()
176 //=======================================================================
177 static bool FillForOtherEdges(const TopoDS_Shape& F1,
178 const TopoDS_Shape& E1,
179 const TopoDS_Shape& V1,
180 TopTools_IndexedDataMapOfShapeShape& FF)
182 //cout<<"FillForOtherEdges"<<endl;
183 // find other pairs for vertexes and edges
184 // creating map of vertex edges for both faces
185 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
186 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
187 if (!FF.Contains(F1))
188 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
189 if (!FF.Contains(E1))
190 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
191 if (!FF.Contains(V1))
192 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
193 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
194 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
195 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
196 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
197 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
199 TopoDS_Edge ES1 = TopoDS::Edge(E1);
200 TopoDS_Edge ES2 = TopoDS::Edge(E2);
201 TopoDS_Shape VS1 = V1;
202 TopoDS_Shape VS2 = V2;
204 ShapeAnalysis_Edge sae;
206 if (!aMapVertEdge1.Contains(VS1))
207 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
208 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
209 //TopoDS_Shape E1next;
210 TopTools_ListIteratorOfListOfShape anIter1(aList1);
211 if (anIter1.Value().IsSame(ES1)) {
214 //E1next = anIter1.Value();
215 if (!aMapVertEdge2.Contains(VS2))
216 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
217 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
218 //TopoDS_Shape E2next;
219 TopTools_ListIteratorOfListOfShape anIter2(aList2);
220 if (anIter2.Value().IsSame(ES2)) {
223 //E2next = anIter2.Value();
224 //ES1 = TopoDS::Edge(E1next);
225 //ES2 = TopoDS::Edge(E2next);
226 ES1 = TopoDS::Edge(anIter1.Value());
227 ES2 = TopoDS::Edge(anIter2.Value());
228 if (!FF.Contains(ES1)) {
231 if (VS1.IsSame(sae.FirstVertex(ES1)))
232 VS1 = sae.LastVertex(ES1);
234 VS1 = sae.FirstVertex(ES1);
235 if (VS2.IsSame(sae.FirstVertex(ES2)))
236 VS2 = sae.LastVertex(ES2);
238 VS2 = sae.FirstVertex(ES2);
241 if (!FF.Contains(VS1)) {
249 //=======================================================================
250 //function : FillCorrespondingEdges
251 //purpose : auxilary for CreatePipeForShellSections()
252 //=======================================================================
253 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
254 const TopoDS_Shape& FS2,
255 const TopoDS_Vertex& aLoc1,
256 const TopoDS_Vertex& aLoc2,
257 const TopoDS_Wire& aWirePath,
258 TopTools_IndexedDataMapOfShapeShape& FF)
260 //cout<<"FillCorrespondingEdges"<<endl;
261 // find corresponding edges
262 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
263 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
264 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
265 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
266 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
267 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
268 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
269 if (theBestMode == GeomFill_IsDiscreteTrihedron)
270 aBuilder.SetDiscreteMode();
271 aBuilder.Add(aWire1, aLoc1);
272 aBuilder.Add(aWire2, aLoc2);
273 if (!aBuilder.IsReady()) {
277 BuildPipeShell(aBuilder);
279 TopoDS_Shape aShape = aBuilder.Shape();
287 BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
289 ShapeAnalysis_Edge sae;
290 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
291 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
292 TopTools_MapOfShape Vs1,Vs2;
294 exp.Init(FS1, TopAbs_EDGE);
295 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
296 TopoDS_Vertex V11 = sae.FirstVertex(E1);
297 TopoDS_Vertex V21 = sae.LastVertex(E1);
298 gp_Pnt P11 = BRep_Tool::Pnt(V11);
299 gp_Pnt P21 = BRep_Tool::Pnt(V21);
300 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
301 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
302 // find corresponding vertexes from created shape
303 TopoDS_Vertex VN11,VN21;
304 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
305 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
306 gp_Pnt P = BRep_Tool::Pnt(V);
307 if (P.Distance(P11)<tol) {
310 if (P.Distance(P21)<tol) {
314 // find edge contains VN11 and VN21 and corresponding vertexes
315 TopoDS_Vertex VN12,VN22;
316 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
317 TopoDS_Shape F = exp.Current();
318 TopExp_Explorer expe;
320 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
321 TopoDS_Edge E = TopoDS::Edge(expe.Current());
322 TopoDS_Vertex VF = sae.FirstVertex(E);
323 TopoDS_Vertex VL = sae.LastVertex(E);
324 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
330 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
331 TopoDS_Edge E = TopoDS::Edge(expe.Current());
332 TopoDS_Vertex VF = sae.FirstVertex(E);
333 TopoDS_Vertex VL = sae.LastVertex(E);
334 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
336 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
338 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
340 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
346 // find vertexes from FS2 corresponded to VN12 and VN22
347 // and find edge from FS2 contains V12 and V22,
348 // this edge will be corresponded to edge E1
349 TopoDS_Vertex V12,V22;
350 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
351 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
352 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
353 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
355 TopExp_Explorer expe;
356 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
357 TopoDS_Edge E = TopoDS::Edge(expe.Current());
358 TopoDS_Vertex VF = sae.FirstVertex(E);
359 TopoDS_Vertex VL = sae.LastVertex(E);
360 gp_Pnt PF = BRep_Tool::Pnt(VF);
361 gp_Pnt PL = BRep_Tool::Pnt(VL);
362 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
368 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
379 // find other pairs for vertexes and edges
380 // creating map of vertex edges for both faces
381 return FillForOtherEdges(FS1,E1,V21,FF);
386 //=======================================================================
387 //function : FillCorrespondingEdges
388 //purpose : auxilary for CreatePipeShellsWithoutPath()
389 //=======================================================================
390 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
391 const TopoDS_Shape& FS2,
392 const TopoDS_Vertex& aLoc1,
393 const TopoDS_Vertex& aLoc2,
394 TopTools_IndexedDataMapOfShapeShape& FF)
396 //cout<<"FillCorrespondingEdges"<<endl;
398 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
399 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
402 ShapeAnalysis_Edge sae;
403 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
404 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
405 TopTools_MapOfShape Vs1,Vs2;
407 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
410 TopExp_Explorer exp1;
411 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
412 E1 = TopoDS::Edge(exp1.Current());
413 TopoDS_Vertex V1 = sae.FirstVertex(E1);
414 TopoDS_Vertex V2 = sae.LastVertex(E1);
415 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
416 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
417 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
418 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
419 if (P1.Distance(Ptmp1)<tol) {
423 if (P1.Distance(Ptmp2)<tol) {
430 TopoDS_Vertex VE21,VE22;
432 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
433 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
434 TopoDS_Vertex V1 = sae.FirstVertex(E);
435 TopoDS_Vertex V2 = sae.LastVertex(E);
436 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
437 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
438 if (P2.Distance(Ptmp1)<tol) {
450 if (P2.Distance(Ptmp2)<tol) {
464 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
465 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
466 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
467 gp_Vec aDir1(PV21,PE21);
468 gp_Vec aDir2(PV21,PE22);
469 double ang1 = aDir.Angle(aDir1);
470 double ang2 = aDir.Angle(aDir2);
471 if (fabs(ang1)<fabs(ang2)) {
484 // find other pairs for vertexes and edges
485 return FillForOtherEdges(FS1,E1,V21,FF);
488 //=======================================================================
489 //function : FindNextPairOfFaces
490 //purpose : auxilary for CreatePipeForShellSections()
491 //=======================================================================
492 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
493 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
494 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
495 TopTools_IndexedDataMapOfShapeShape& FF,
498 //cout<<"FindNextPairOfFaces"<<endl;
499 TopExp_Explorer anExp;
500 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
501 TopoDS_Shape E1 = anExp.Current();
502 if (!FF.Contains(E1)) {
504 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
506 if (!FF.Contains(E1))
507 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
508 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
509 TopExp_Explorer anExpV;
510 anExpV.Init(E1, TopAbs_VERTEX);
511 TopoDS_Shape V1 = anExpV.Current();
512 if (!FF.Contains(V1)) {
514 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
517 if (!aMapEdgeFaces1.Contains(E1))
518 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
519 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
520 if (aList1.Extent()<2)
522 TopTools_ListIteratorOfListOfShape anIter(aList1);
523 if (anIter.Value().IsEqual(aCurFace)) {
526 TopoDS_Shape F1other = anIter.Value();
527 if (FF.Contains(F1other))
530 if (!FF.Contains(aCurFace))
531 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
532 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
533 if (!aMapEdgeFaces2.Contains(E2))
534 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
535 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
536 if (aList2.Extent()<2) {
538 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
540 TopTools_ListIteratorOfListOfShape anIter2(aList2);
541 if (anIter2.Value().IsEqual(F2)) {
544 TopoDS_Shape F2other = anIter2.Value();
545 FF.Add(F1other,F2other);
547 // add pairs of edges to FF
548 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
551 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
554 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
558 //=======================================================================
559 //function : FindFirstPairFaces
560 //purpose : auxilary for Execute()
561 //=======================================================================
562 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
563 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
564 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
566 //cout<<"FindFirstPairFaces"<<endl;
568 // check if vertexes are sub-shapes of sections
569 gp_Pnt P1 = BRep_Tool::Pnt(V1);
570 gp_Pnt P2 = BRep_Tool::Pnt(V2);
571 TopoDS_Vertex V1new,V2new;
573 double mindist = 1.e10;
574 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
575 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
576 gp_Pnt P = BRep_Tool::Pnt(V);
577 double dist = P1.Distance(P);
584 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
585 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
586 gp_Pnt P = BRep_Tool::Pnt(V);
587 double dist = P2.Distance(P);
594 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
595 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
596 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
597 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
598 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
599 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
601 // replace vertexes if it is needed
602 if (!V1.IsSame(V1new)) {
604 P1 = BRep_Tool::Pnt(V1);
605 MESSAGE (" replace V1");
608 MESSAGE (" not replace V1");
609 if (!V2.IsSame(V2new)) {
611 P2 = BRep_Tool::Pnt(V2);
612 MESSAGE (" replace V2");
615 MESSAGE (" not replace V2");
617 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
618 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
619 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
620 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
622 if (!aMapVertFaces1.Contains(V1))
623 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
624 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
625 TopTools_ListIteratorOfListOfShape anIter1(aList1);
626 FS1 = anIter1.Value();
628 double x1=0., y1=0., z1=0.;
630 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
631 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
632 gp_Pnt P = BRep_Tool::Pnt(V);
638 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
640 TColgp_SequenceOfPnt Ps;
641 TopTools_SequenceOfShape Fs;
642 if (!aMapVertFaces2.Contains(V2))
643 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
644 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
645 TopTools_ListIteratorOfListOfShape anIter2(aList2);
646 for (; anIter2.More(); anIter2.Next()) {
647 TopoDS_Shape F = anIter2.Value();
648 double x2=0., y2=0., z2=0.;
650 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
651 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
652 gp_Pnt P = BRep_Tool::Pnt(V);
658 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
665 double MinAng = M_PI;
667 for (; i<=Fs.Length(); i++) {
668 gp_Vec tmpDir(PM1,Ps(i));
669 double ang = fabs(aDir.Angle(tmpDir));
678 //=======================================================================
679 //function : CreatePipeWithDifferentSections
681 //=======================================================================
682 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
683 (const TopoDS_Wire& theWirePath,
684 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
685 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
686 const Standard_Boolean theWithContact,
687 const Standard_Boolean theWithCorrect)
691 TopoDS_Wire aWirePath = theWirePath;
693 Standard_Integer nbBases = theHSeqBases->Length();
694 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
696 if (nbLocs && nbLocs != nbBases) {
697 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
700 TopTools_SequenceOfShape aSeqBases;
701 TopTools_SequenceOfShape aSeqLocs;
702 TopTools_SequenceOfShape aSeqFaces;
703 Standard_Boolean NeedCreateSolid = Standard_False;
705 Standard_Integer i = 1;
706 for (i = 1; i <= nbBases; i++) {
707 if (theHSeqBases->Value(i).IsNull())
710 // Make copy to prevent modifying of base object 0020766 : EDF 1320
711 TopoDS_Shape aShapeBase;
712 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
714 aShapeBase = Copy.Shape();
716 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
718 //if for section was specified face with a few wires then a few
719 // pipes were build and make solid
720 if (aTypeBase == TopAbs_SHELL) {
721 // create wire as boundary contour if shell is no closed
722 // get free boundary shapes
723 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
724 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
725 TopExp_Explorer anExp;
727 Standard_Integer NbWires = 0;
728 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
730 aWire = anExp.Current();
734 Standard_ConstructionError::Raise("Bad shell is used as section ");
736 NeedCreateSolid = Standard_True;
737 aSeqFaces.Append(aShapeBase);
738 aSeqBases.Append(aWire);
740 else if (aTypeBase == TopAbs_FACE) {
741 NeedCreateSolid = Standard_True;
742 //for case one path should be used other type function
743 aSeqFaces.Append(aShapeBase);
744 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
745 for (; aExpW.More(); aExpW.Next()) {
746 TopoDS_Shape aWireProf = aExpW.Current();
747 aSeqBases.Append(aWireProf);
750 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
751 aSeqBases.Append(aShapeBase);
753 else if (aTypeBase == TopAbs_EDGE) {
754 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
755 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
756 aSeqBases.Append(aWireProf);
759 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
760 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
762 aSeqLocs.Append(aShapeLoc);
766 nbLocs = aSeqLocs.Length();
769 TopTools_SequenceOfShape Edges;
771 // we have to check that each location shape is a vertex from
772 // path and update aSeqLocs if it is needed (and possible)
773 TColgp_SequenceOfPnt PLocs;
774 for (i=1; i<=nbLocs; i++) {
775 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
776 PLocs.Append(BRep_Tool::Pnt(V));
778 //TopTools_SequenceOfShape Edges;
779 TopExp_Explorer anExp;
780 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
781 Edges.Append(anExp.Current());
783 int nbEdges = Edges.Length();
784 ShapeAnalysis_Edge sae;
785 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
786 double tol = BRep_Tool::Tolerance(edge);
787 TopoDS_Vertex VF = sae.FirstVertex(edge);
788 gp_Pnt PF = BRep_Tool::Pnt(VF);
789 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
790 if (PF.Distance(PLocs.First()) > tol) {
791 Standard_ConstructionError::Raise
792 ("First location shapes is not coincided with first vertex of aWirePath");
794 aSeqLocs.ChangeValue(1) = VF;
795 edge = TopoDS::Edge(Edges.Last());
796 tol = BRep_Tool::Tolerance(edge);
797 TopoDS_Vertex VL = sae.LastVertex(edge);
798 gp_Pnt PL = BRep_Tool::Pnt(VL);
799 if (PL.Distance(PLocs.Last()) > tol) {
800 Standard_ConstructionError::Raise
801 ("Last location shapes is not coincided with last vertex of aWirePath");
803 aSeqLocs.ChangeValue(nbLocs) = VL;
805 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
806 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
807 tol = BRep_Tool::Tolerance(edge);
808 TopoDS_Vertex V1 = sae.FirstVertex(E);
809 TopoDS_Vertex V2 = sae.LastVertex(E);
810 gp_Pnt P1 = BRep_Tool::Pnt(V1);
811 gp_Pnt P2 = BRep_Tool::Pnt(V2);
812 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
813 aSeqLocs.ChangeValue(jcurr) = V2;
817 // find distance between E and aLocs(jcurr)
819 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
820 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
821 if (PPCurve.NbPoints()>0 &&
822 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
823 double param = PPCurve.Parameter(1);
826 // split current edge
827 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
828 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
833 if (Pfp.Distance(P1)<tol) {
834 B.MakeEdge(E1,tc1,tol);
836 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
837 B.Add(E1,TopoDS::Vertex(tmpV));
838 B.MakeEdge(E2,tc2,tol);
839 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
840 B.Add(E2,TopoDS::Vertex(tmpV));
844 B.MakeEdge(E1,tc2,tol);
845 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
846 B.Add(E1,TopoDS::Vertex(tmpV));
849 B.MakeEdge(E2,tc1,tol);
851 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
852 B.Add(E2,TopoDS::Vertex(tmpV));
857 Edges.InsertAfter(i-1,E1);
858 Edges.InsertAfter(i,E2);
862 if (nbEdges<Edges.Length()) {
863 // one of edges was splitted => we have to update WirePath
867 for (i=1; i<=Edges.Length(); i++) {
868 B.Add(W,TopoDS::Edge(Edges.Value(i)));
874 // check curvature of wire for condition that
875 // max summary angle between directions along
876 // wire path must be < 4*PI. If not - split wire
877 // and seguences of shapes, perform pipe for each
878 // and make sewing after that
883 if ( Edges.Length() > 0 ) {
884 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
887 SumAng = fabs(Vec1.Angle(Vec2));
891 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
893 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
894 for (i=2; i<=Edges.Length(); i++) {
895 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
896 double tol = BRep_Tool::Tolerance(edge);
897 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
899 double ang = fabs(Vec1.Angle(Vec2));
903 SplitEdgeNums.Append(i-1);
905 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
906 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
907 gp_Pnt P = BRep_Tool::Pnt(aVert);
908 if (P1.Distance(P) < tol) {
909 SplitLocNums.Append(j);
919 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
920 TopTools_SequenceOfShape aSeqRes;
921 int nn, num1 = 1, num2 = 1;
922 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
923 // create wirepath and sequences of shapes
927 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
928 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
930 num1 = SplitEdgeNums.Value(nn) + 1;
931 TopTools_SequenceOfShape aTmpSeqBases;
932 TopTools_SequenceOfShape aTmpSeqLocs;
933 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
934 aTmpSeqBases.Append(aSeqBases.Value(i));
935 aTmpSeqLocs.Append(aSeqLocs.Value(i));
937 num2 = SplitLocNums.Value(nn);
939 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
940 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
941 if (theBestMode == GeomFill_IsDiscreteTrihedron)
942 aBuilder.SetDiscreteMode();
943 Standard_Integer nbShapes = aTmpSeqBases.Length();
944 for (i=1; i<=nbShapes; i++) {
945 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
946 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
947 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
949 if (!aBuilder.IsReady()) {
950 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
953 BuildPipeShell(aBuilder);
955 TopoDS_Shape resShape = aBuilder.Shape();
956 aSeqRes.Append(resShape);
958 // create wirepath and sequences of shapes for last part
962 for (i=num1; i<=Edges.Length(); i++) {
963 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
965 TopTools_SequenceOfShape aTmpSeqBases;
966 TopTools_SequenceOfShape aTmpSeqLocs;
967 for (i=num2; i<=aSeqLocs.Length(); i++) {
968 aTmpSeqBases.Append(aSeqBases.Value(i));
969 aTmpSeqLocs.Append(aSeqLocs.Value(i));
971 // make pipe for last part
972 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
973 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
974 if (theBestMode == GeomFill_IsDiscreteTrihedron)
975 aBuilder.SetDiscreteMode();
976 Standard_Integer nbShapes = aTmpSeqBases.Length();
977 for (i=1; i<=nbShapes; i++) {
978 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
979 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
980 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
982 if (!aBuilder.IsReady()) {
983 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
986 BuildPipeShell(aBuilder);
988 TopoDS_Shape resShape = aBuilder.Shape();
989 aSeqRes.Append(resShape);
990 // make sewing for result
991 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
992 aSewing->SetTolerance(Precision::Confusion());
993 aSewing->SetFaceMode(Standard_True);
994 aSewing->SetFloatingEdgesMode(Standard_False);
995 aSewing->SetNonManifoldMode(Standard_False);
996 for (i=1; i<=aSeqRes.Length(); i++) {
997 aSewing->Add(aSeqRes.Value(i));
1000 aShape = aSewing->SewedShape();
1003 // old implementation without splitting
1004 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1005 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1006 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1007 aBuilder.SetDiscreteMode();
1009 Standard_Integer nbShapes = aSeqBases.Length();
1010 Standard_Integer step = nbShapes/nbBases;
1012 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1013 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1015 Standard_Integer ind =0;
1016 Standard_Real aTolConf = Precision::Confusion();
1017 Standard_Real aTolAng = Precision::Angular();
1019 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1020 TopTools_SequenceOfShape usedBases;
1021 Standard_Integer j = 1;
1022 for (; j <= nbBases; j++) {
1023 ind = i + (j-1)*step;
1024 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1025 usedBases.Append(aWireProf);
1027 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1028 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1029 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1032 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1034 if (!aBuilder.IsReady()) {
1035 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1038 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1040 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1042 if (isDone && NeedCreateSolid) {
1043 isDone = aBuilder.MakeSolid();
1047 Standard_ConstructionError::Raise("Pipe construction failure");
1049 aShape = aBuilder.Shape();
1050 aSeqFaces.Append(aShape);
1051 for (j = 1; j <=usedBases.Length(); j++)
1052 aBuilder.Delete(usedBases.Value(j));
1059 //=======================================================================
1060 //function : CreatePipeForShellSections
1061 //purpose : auxilary for Execute()
1062 //=======================================================================
1063 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1064 GEOMImpl_IPipe* aCI)
1066 //cout<<"CreatePipeForShellSections"<<endl;
1071 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1072 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1073 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1074 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1075 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1076 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1078 Standard_Integer nbBases = aBasesObjs->Length(),
1079 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1080 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1082 if (nbLocs != nbBases) {
1083 if (aCI) delete aCI;
1084 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1086 if (nbSubBases && nbSubBases != nbBases) {
1087 if (aCI) delete aCI;
1088 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1091 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1093 TopTools_SequenceOfShape VLocs;
1094 for (i=1; i<=nbBases; i++) {
1095 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1096 if (anItemLoc.IsNull())
1098 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1099 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1100 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1102 VLocs.Append(aShapeLoc);
1104 nbLocs = VLocs.Length();
1105 if (nbLocs != nbBases) {
1106 if (aCI) delete aCI;
1107 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1109 // split wire path by location points
1110 TColgp_SequenceOfPnt PLocs;
1111 for (i=1; i<=nbLocs; i++) {
1112 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1113 PLocs.Append(BRep_Tool::Pnt(V));
1116 TopTools_SequenceOfShape Edges;
1117 TopTools_SequenceOfShape Wires;
1118 ShapeAnalysis_Edge sae;
1121 TopExp_Explorer anExp;
1122 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1123 Edges.Append(anExp.Current());
1125 Standard_Integer Num1 = 0;
1126 Standard_Integer Num2 = 0;
1127 for (i=1; i<=Edges.Length(); i++) {
1128 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1129 double tol = BRep_Tool::Tolerance(E);
1130 TopoDS_Vertex V1 = sae.FirstVertex(E);
1131 TopoDS_Vertex V2 = sae.LastVertex(E);
1132 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1133 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1134 if (P1.Distance(PLocs.First()) < tol) {
1137 if (P2.Distance(PLocs.Last()) < tol) {
1141 if (Num1>0 && Num2>0) {
1144 for (i=Num1; i<=Num2; i++) {
1145 B.Add(W,Edges.Value(i));
1150 Wires.Append(aWirePath);
1154 TopExp_Explorer anExp;
1155 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1156 Edges.Append(anExp.Current());
1158 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1159 double tol = BRep_Tool::Tolerance(edge);
1160 TopoDS_Vertex VF = sae.FirstVertex(edge);
1161 gp_Pnt PF = BRep_Tool::Pnt(VF);
1162 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1163 if (PF.Distance(PLocs.First()) > tol) {
1164 if (aCI) delete aCI;
1165 Standard_ConstructionError::Raise
1166 ("First location shapes is not coincided with first vertex of aWirePath");
1168 VLocs.ChangeValue(1) = VF;
1169 edge = TopoDS::Edge(Edges.Last());
1170 tol = BRep_Tool::Tolerance(edge);
1171 TopoDS_Vertex VL = sae.LastVertex(edge);
1172 gp_Pnt PL = BRep_Tool::Pnt(VL);
1173 if (PL.Distance(PLocs.Last()) > tol) {
1174 if (aCI) delete aCI;
1175 Standard_ConstructionError::Raise
1176 ("Last location shapes is not coincided with last vertex of aWirePath");
1178 VLocs.ChangeValue(nbLocs) = VL;
1180 TopTools_SequenceOfShape tmpEdges;
1181 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1182 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1183 tol = BRep_Tool::Tolerance(E);
1184 TopoDS_Vertex V1 = sae.FirstVertex(E);
1185 TopoDS_Vertex V2 = sae.LastVertex(E);
1186 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1187 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1188 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1189 // make wire from current edge and add created
1193 for (j=1; j<=tmpEdges.Length(); j++)
1194 B.Add(W,tmpEdges.Value(j));
1197 VLocs.ChangeValue(jcurr) = V2;
1202 // find distance between E and aLocs(jcurr)
1204 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1205 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1206 if (PPCurve.NbPoints()>0 &&
1207 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1208 double param = PPCurve.Parameter(1);
1211 // split current edge
1212 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1213 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1217 if (Pfp.Distance(P1)<tol) {
1218 B.MakeEdge(E1,tc1,tol);
1220 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1221 B.Add(E1,TopoDS::Vertex(tmpV));
1222 tmpEdges.Append(E1);
1223 B.MakeEdge(E2,tc2,tol);
1224 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1225 B.Add(E2,TopoDS::Vertex(tmpV));
1229 B.MakeEdge(E1,tc2,tol);
1230 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1231 B.Add(E1,TopoDS::Vertex(tmpV));
1234 tmpEdges.Append(E1);
1235 B.MakeEdge(E2,tc1,tol);
1237 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1238 B.Add(E2,TopoDS::Vertex(tmpV));
1241 // create wire from tmpEdges
1244 for (j=1; j<=tmpEdges.Length(); j++)
1245 B.Add(W,tmpEdges.Value(j));
1250 Edges.InsertAfter(i-1,E1);
1251 Edges.InsertAfter(i,E2);
1258 // create wire from other edges
1261 for (; i<=Edges.Length(); i++)
1262 B.Add(W,Edges.Value(i));
1264 //cout<<"Wires.Length()="<<Wires.Length()<<endl;
1267 if (Wires.Length() != nbLocs-1) {
1268 if (aCI) delete aCI;
1269 Standard_ConstructionError::Raise
1270 ("One of location shapes is not lied on the path");
1273 //TopTools_SequenceOfShape aSeqBases;
1274 //TopTools_SequenceOfShape aSeqSubBases;
1275 //TopTools_SequenceOfShape aSeqFaces;
1276 TopoDS_Compound aComp;
1277 B.MakeCompound(aComp);
1278 for (i = 1; i < nbBases; i++) {
1279 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1281 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1282 if (anItem1.IsNull())
1284 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1285 if (aRefBase1.IsNull())
1287 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1288 if (aShBase1.IsNull())
1290 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1292 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1293 if (anItem2.IsNull())
1295 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1296 if (aRefBase2.IsNull())
1298 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1299 if (aShBase2.IsNull())
1301 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1303 //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
1305 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1306 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1308 if (aCI) delete aCI;
1309 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1312 bool CreateFewSolids = false;
1314 TopExp_Explorer anExp;
1315 Standard_Integer nbf1 = 0;
1316 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1319 Standard_Integer nbf2 = 0;
1320 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1324 CreateFewSolids = true;
1328 // check orientation of sections
1329 bool NeedReverse = false;
1332 anExp.Init(aShBase1, TopAbs_FACE);
1333 TopoDS_Shape aFace = anExp.Current();
1334 TColgp_SequenceOfPnt aPnts;
1335 double xc=0, yc=0, zc=0;
1336 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1337 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1338 aPnts.Append(BRep_Tool::Pnt(V));
1339 xc += aPnts.Last().X();
1340 yc += aPnts.Last().Y();
1341 zc += aPnts.Last().Z();
1343 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1344 gp_Vec V1(PC,aPnts.Value(1));
1345 gp_Vec V2(PC,aPnts.Value(2));
1346 gp_Vec VN = V1.Crossed(V2);
1347 for (int ip=2; ip<aPnts.Length(); ip++) {
1348 V1 = gp_Vec(PC,aPnts.Value(ip));
1349 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1350 VN.Add(V1.Crossed(V2));
1353 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
1355 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1356 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1357 double tol = BRep_Tool::Tolerance(edge);
1358 TopoDS_Vertex VF = sae.FirstVertex(edge);
1359 gp_Pnt PF = BRep_Tool::Pnt(VF);
1360 if (PF.Distance(PLoc) < tol) {
1362 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1365 if (P1.Distance(PLoc) < tol) {
1366 C->D0(fp+(lp-fp)/100,P2);
1370 C->D0(lp+(fp-lp)/100,P2);
1372 PathNorm = gp_Vec(P1,P2);
1376 TopoDS_Vertex VL = sae.LastVertex(edge);
1377 gp_Pnt PL = BRep_Tool::Pnt(VL);
1378 if (PL.Distance(PLoc) < tol) {
1380 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1383 if (P1.Distance(PLoc) < tol) {
1384 C->D0(fp+(lp-fp)/100,P2);
1388 C->D0(lp+(fp-lp)/100,P2);
1390 PathNorm = gp_Vec(P2,P1);
1395 cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1396 cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1397 if (fabs(VN.Angle(PathNorm))>PI/2.) {
1404 anExp.Init(aShBase2, TopAbs_FACE);
1405 TopoDS_Shape aFace = anExp.Current();
1406 TColgp_SequenceOfPnt aPnts;
1407 double xc=0, yc=0, zc=0;
1408 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1409 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1410 aPnts.Append(BRep_Tool::Pnt(V));
1411 xc += aPnts.Last().X();
1412 yc += aPnts.Last().Y();
1413 zc += aPnts.Last().Z();
1415 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1416 gp_Vec V1(PC,aPnts.Value(1));
1417 gp_Vec V2(PC,aPnts.Value(2));
1418 gp_Vec VN = V1.Crossed(V2);
1419 for (int ip=2; ip<aPnts.Length(); ip++) {
1420 V1 = gp_Vec(PC,aPnts.Value(ip));
1421 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1422 VN.Add(V1.Crossed(V2));
1425 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
1427 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1428 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1429 double tol = BRep_Tool::Tolerance(edge);
1430 TopoDS_Vertex VF = sae.FirstVertex(edge);
1431 gp_Pnt PF = BRep_Tool::Pnt(VF);
1432 if (PF.Distance(PLoc) < tol) {
1434 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1437 if (P1.Distance(PLoc) < tol) {
1438 C->D0(fp+(lp-fp)/100,P2);
1442 C->D0(lp+(fp-lp)/100,P2);
1444 PathNorm = gp_Vec(P2,P1);
1448 TopoDS_Vertex VL = sae.LastVertex(edge);
1449 gp_Pnt PL = BRep_Tool::Pnt(VL);
1450 if (PL.Distance(PLoc) < tol) {
1452 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1455 if (P1.Distance(PLoc) < tol) {
1456 C->D0(fp+(lp-fp)/100,P2);
1460 C->D0(lp+(fp-lp)/100,P2);
1462 PathNorm = gp_Vec(P2,P1);
1467 //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1468 //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1469 if (fabs(VN.Angle(PathNorm))>PI/2.)
1474 if (!CreateFewSolids) {
1475 // we can create only one solid
1476 TopoDS_Shape aWire1, aWire2;
1478 if (aType1==TopAbs_SHELL) {
1479 // create wire as boundary contour if shell is no closed
1480 // get free boundary shapes
1481 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1482 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1483 //TopExp_Explorer anExp;
1484 Standard_Integer NbWires = 0;
1485 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1487 aWire1 = anExp.Current();
1491 if (aCI) delete aCI;
1492 Standard_ConstructionError::Raise("Bad shell is used as section ");
1495 else { // aType1==TopAbs_FACE
1496 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1497 aWire1 = aExpW.Current();
1500 if (aType2==TopAbs_SHELL) {
1501 // create wire as boundary contour if shell is no closed
1502 // get free boundary shapes
1503 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1504 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1505 //TopExp_Explorer anExp;
1506 Standard_Integer NbWires = 0;
1507 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1509 aWire2 = anExp.Current();
1513 if (aCI) delete aCI;
1514 Standard_ConstructionError::Raise("Bad shell is used as section ");
1517 else { // aType2==TopAbs_FACE
1518 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1519 aWire2 = aExpW.Current();
1521 // make pipe using aWire1 and aWire2
1522 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1523 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1524 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1525 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1526 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1527 aBuilder.SetDiscreteMode();
1528 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1529 aWithContact, aWithCorrect);
1530 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1531 aWithContact, aWithCorrect);
1532 if (!aBuilder.IsReady()) {
1533 if (aCI) delete aCI;
1534 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1537 BuildPipeShell(aBuilder);
1539 TopoDS_Shape aShape = aBuilder.Shape();
1540 TopoDS_Shell aShell;
1541 B.MakeShell(aShell);
1542 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1543 B.Add(aShell,anExp.Current());
1545 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1546 B.Add(aShell,anExp.Current());
1548 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1549 B.Add(aShell,anExp.Current());
1551 // make sewing for this shell
1552 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1553 aSewing->SetTolerance(Precision::Confusion());
1554 aSewing->SetFaceMode(Standard_True);
1555 aSewing->SetFloatingEdgesMode(Standard_False);
1556 aSewing->SetNonManifoldMode(Standard_False);
1557 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1558 aSewing->Add(anExp.Current());
1561 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1562 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1563 aShell = TopoDS::Shell(aSewShape);
1564 GProp_GProps aSystem;
1565 BRepGProp::VolumeProperties(aShell, aSystem);
1566 if (aSystem.Mass()<0) {
1569 if (BRep_Tool::IsClosed(aShell)) {
1570 TopoDS_Solid aSolid;
1571 B.MakeSolid(aSolid);
1572 B.Add(aSolid,aShell);
1573 B.Add(aComp,aSolid);
1576 B.Add(aComp,aShell);
1580 B.Add(aComp,aShell);
1585 // main block - creation few solids (for each pair of faces)
1586 TopTools_MapOfShape aFaces1,aFaces2;
1587 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1588 aFaces1.Add(anExp.Current());
1590 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1591 aFaces2.Add(anExp.Current());
1593 // creating map of edge faces
1594 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1595 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1596 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1597 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1599 // constuct map face->face
1600 TopTools_IndexedDataMapOfShapeShape FF;
1601 TopoDS_Shape FS1,FS2;
1602 if (nbSubBases==0) {
1603 // find edge the most distant from location point
1604 // (this edge is not shared by two faces)
1605 double maxdist = 0.;
1607 TopoDS_Vertex V11,V21;
1608 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1609 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1610 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1611 if (aList.Extent()>1)
1613 TopExp_Explorer expv;
1614 expv.Init(tmp, TopAbs_VERTEX);
1615 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1617 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1618 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1619 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1620 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1625 TopTools_ListIteratorOfListOfShape anIter(aList);
1626 FS1 = anIter.Value();
1630 // main direction for comparing
1631 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1632 // find corresponding edge from next section
1633 double minang = M_PI;
1634 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1635 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1637 TopoDS_Vertex V12,V22;
1638 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1639 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1640 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1641 if (aList.Extent()>1)
1643 TopExp_Explorer expv;
1644 expv.Init(tmp, TopAbs_VERTEX);
1645 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1647 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1648 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1649 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1650 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1651 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1652 TopoDS_Vertex V1,V2;
1655 V1 = V2tmp; P1 = P2tmp;
1656 V2 = V1tmp; P2 = P1tmp;
1659 V1 = V1tmp; P1 = P1tmp;
1660 V2 = V2tmp; P2 = P2tmp;
1662 gp_Vec Vec1(P11,P1);
1663 gp_Vec Vec2(P21,P2);
1664 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1669 TopTools_ListIteratorOfListOfShape anIter(aList);
1670 FS2 = anIter.Value();
1674 // put all pairs to map FF
1680 // add pairs of edges to FF
1681 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1683 if (aCI) delete aCI;
1684 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1690 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1691 if (anItem.IsNull()) {
1692 if (aCI) delete aCI;
1693 Standard_ConstructionError::Raise("Invalid subbase shape");
1695 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1696 if (aRefBase.IsNull()) {
1697 if (aCI) delete aCI;
1698 Standard_ConstructionError::Raise("Invalid subbase shape");
1700 TopoDS_Shape aSh = aRefBase->GetValue();
1702 if (aCI) delete aCI;
1703 Standard_ConstructionError::Raise("Invalid subbase shape");
1705 if (aSh.ShapeType()!=TopAbs_FACE) {
1706 if (aCI) delete aCI;
1707 Standard_ConstructionError::Raise("Invalid subbase shape");
1712 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1713 if (anItem.IsNull()) {
1714 if (aCI) delete aCI;
1715 Standard_ConstructionError::Raise("Invalid subbase shape");
1717 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1718 if (aRefBase.IsNull()) {
1719 if (aCI) delete aCI;
1720 Standard_ConstructionError::Raise("Invalid subbase shape");
1722 TopoDS_Shape aSh = aRefBase->GetValue();
1724 if (aCI) delete aCI;
1725 Standard_ConstructionError::Raise("Invalid subbase shape");
1727 if (aSh.ShapeType()!=TopAbs_FACE) {
1728 if (aCI) delete aCI;
1729 Standard_ConstructionError::Raise("Invalid subbase shape");
1734 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1735 if (aCI) delete aCI;
1736 Standard_ConstructionError::Raise("Invalid subbase shape");
1741 // add pairs of edges to FF
1742 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1743 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1745 if (aCI) delete aCI;
1746 Standard_ConstructionError::Raise("Can not create correct pipe");
1750 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1752 // make pipe for each pair of faces
1753 for (j=1; j<=FF.Extent(); j++) {
1754 TopoDS_Shape F1 = FF.FindKey(j);
1755 if (F1.ShapeType() != TopAbs_FACE)
1757 TopoDS_Shape F2 = FF.FindFromIndex(j);
1758 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1759 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1760 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1761 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1762 // make pipe using aWire1 and aWire2
1763 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1764 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1765 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1766 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1767 aBuilder.SetDiscreteMode();
1768 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1769 aWithContact, aWithCorrect);
1770 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1771 aWithContact, aWithCorrect);
1772 if (!aBuilder.IsReady()) {
1773 if (aCI) delete aCI;
1774 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1777 BuildPipeShell(aBuilder);
1779 TopoDS_Shape aShape = aBuilder.Shape();
1780 TopoDS_Shell aShell;
1781 B.MakeShell(aShell);
1782 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1783 B.Add(aShell,anExp.Current());
1788 // make sewing for this shell
1789 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1790 aSewing->SetTolerance(Precision::Confusion());
1791 aSewing->SetFaceMode(Standard_True);
1792 aSewing->SetFloatingEdgesMode(Standard_False);
1793 aSewing->SetNonManifoldMode(Standard_False);
1794 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1795 aSewing->Add(anExp.Current());
1798 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1799 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1800 aShell = TopoDS::Shell(aSewShape);
1801 GProp_GProps aSystem;
1802 BRepGProp::VolumeProperties(aShell, aSystem);
1803 if (aSystem.Mass()<0) {
1804 //cout<<"aSewShape is reversed"<<endl;
1807 if (BRep_Tool::IsClosed(aShell)) {
1808 TopoDS_Solid aSolid;
1809 B.MakeSolid(aSolid);
1810 B.Add(aSolid,aShell);
1811 B.Add(aComp,aSolid);
1814 B.Add(aComp,aShell);
1818 B.Add(aComp,aShell);
1826 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
1830 //=======================================================================
1831 //function : CreatePipeShellsWithoutPath
1832 //purpose : auxilary for Execute()
1833 //=======================================================================
1834 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1836 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1840 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1842 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1843 // vertex for recognition
1844 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1846 Standard_Integer nbBases = aBasesObjs->Length(),
1847 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1849 if (nbv != nbBases) {
1850 if (aCI) delete aCI;
1851 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1854 TopTools_SequenceOfShape SecVs,Bases;
1855 for (i=1; i<=nbBases; i++) {
1857 Handle(Standard_Transient) anItem = VObjs->Value(i);
1858 if (anItem.IsNull())
1860 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1861 TopoDS_Shape V = aRef->GetValue();
1862 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1866 anItem = aBasesObjs->Value(i);
1867 if (anItem.IsNull())
1869 aRef = Handle(GEOM_Function)::DownCast(anItem);
1870 TopoDS_Shape aSh = aRef->GetValue();
1875 nbv = SecVs.Length();
1876 nbBases = Bases.Length();
1877 if (nbv != nbBases) {
1878 if (aCI) delete aCI;
1879 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1882 TopoDS_Compound aComp;
1883 B.MakeCompound(aComp);
1885 for (i = 1; i < nbBases; i++) {
1886 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1887 TopoDS_Shape aShBase1 = Bases.Value(i);
1888 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1889 TopExp_Explorer anExp;
1890 Standard_Integer nbf1 = 0;
1891 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1894 Standard_Integer nbf2 = 0;
1895 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1898 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1900 if (aCI) delete aCI;
1901 Standard_ConstructionError::Raise("Different number of faces in the sections");
1904 TopTools_MapOfShape aFaces1,aFaces2;
1905 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1906 aFaces1.Add(anExp.Current());
1908 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1909 aFaces2.Add(anExp.Current());
1912 // creating map of edge faces
1913 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1914 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1915 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1916 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1918 // constuct map face->face (and sub-shapes)
1919 TopTools_IndexedDataMapOfShapeShape FF;
1920 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
1921 TopoDS_Shape FS1, FS2;
1922 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
1923 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
1924 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
1927 MESSAGE (" first pair of corresponding faces is found");
1929 // add pairs of edges and vertexes to FF
1930 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
1932 if (aCI) delete aCI;
1933 Standard_ConstructionError::Raise("Can not create correct pipe");
1935 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
1937 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1938 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
1940 // make pipe for each pair of faces
1941 // auxilary map vertex->edge for created pipe edges
1942 TopTools_IndexedDataMapOfShapeShape VPE;
1943 ShapeAnalysis_Edge sae;
1944 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
1946 for (j=1; j<=FF.Extent(); j++) {
1947 TopoDS_Shape F1 = FF.FindKey(j);
1948 if (F1.ShapeType() != TopAbs_FACE)
1950 TopoDS_Shape F2 = FF.FindFromIndex(j);
1953 //if (nbff!=3) continue;
1955 MESSAGE (" make pipe for "<<nbff<<" face");
1957 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
1958 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1959 Handle(Geom_RectangularTrimmedSurface) RTS =
1960 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
1961 S1 = RTS->BasisSurface();
1963 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
1964 if (Pln1.IsNull()) {
1965 if (aCI) delete aCI;
1966 Standard_ConstructionError::Raise("Surface from face is not plane");
1968 gp_Vec aDir1(Pln1->Axis().Direction());
1970 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
1971 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1972 Handle(Geom_RectangularTrimmedSurface) RTS =
1973 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
1974 S2 = RTS->BasisSurface();
1976 Handle(Geom_Plane) Pln2 =
1977 Handle(Geom_Plane)::DownCast(S2);
1978 if (Pln2.IsNull()) {
1979 if (aCI) delete aCI;
1980 Standard_ConstructionError::Raise("Surface from face is not plane");
1982 gp_Vec aDir2(Pln2->Axis().Direction());
1984 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
1985 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
1987 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
1989 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
1992 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
1993 TopTools_SequenceOfShape aNewFs;
1995 for (; anExpE.More(); anExpE.Next()) {
1996 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
1998 if (!FF.Contains(E1))
1999 MESSAGE ("map FF not contains key E1");
2001 if (VPE.Contains(E1)) {
2002 aNewFs.Append(VPE.FindFromKey(E1));
2004 MESSAGE (" using existed face");
2009 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2010 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2011 TopoDS_Vertex V2 = sae.LastVertex(E1);
2012 if (!FF.Contains(V1))
2013 MESSAGE ("map FF not contains key V1");
2014 if (!FF.Contains(V2))
2015 MESSAGE ("map FF not contains key V2");
2016 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2017 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2018 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2019 if (Vtmp.IsSame(V4))
2021 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2022 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2023 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2024 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2027 Handle(Geom_BSplineCurve) C2;
2028 if (VPE.Contains(V2)) {
2029 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2031 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2034 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2035 HAP->SetValue(1,P2);
2036 HAP->SetValue(2,P3);
2037 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2038 anInt.Load(aDir1,aDir2);
2041 B.MakeEdge(E2,C2,1.e-7);
2042 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2043 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2048 Handle(Geom_BSplineCurve) C4;
2049 if (VPE.Contains(V1)) {
2050 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2052 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2055 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2056 HAP->SetValue(1,P1);
2057 HAP->SetValue(2,P4);
2058 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2059 anInt.Load(aDir1,aDir2);
2062 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2063 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2064 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2073 B.Add(W,E4.Reversed());
2074 //cout<<" wire for edge "<<nbee<<" is created"<<endl;
2075 //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
2080 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2081 //bool IsConicC1 = false;
2082 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2083 // IsConicC1 = true;
2084 // cout<<"C1 - Geom_Conic"<<endl;
2086 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2087 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2090 // double tol = BRep_Tool::Tolerance(E1);
2091 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2092 // C1 = ApxC1.Curve();
2094 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2095 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2096 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2101 Handle(Geom_BSplineCurve) CE1 =
2102 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2103 if (CE1->Degree()<3)
2104 CE1->IncreaseDegree(3);
2105 Handle(Geom_BSplineCurve) CE2 =
2106 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2107 if (CE2->Degree()<3)
2108 CE2->IncreaseDegree(3);
2109 Handle(Geom_BSplineCurve) CE3 =
2110 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2111 if (CE3->Degree()<3)
2112 CE3->IncreaseDegree(3);
2113 Handle(Geom_BSplineCurve) CE4 =
2114 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2115 if (CE4->Degree()<3)
2116 CE4->IncreaseDegree(3);
2117 //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
2118 // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
2119 //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
2120 // os<<"DrawTrSurf_BSplineCurve"<<endl;
2121 // GeomTools::Write(CE1,os);
2125 Handle(Geom_Surface) BS;
2127 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2128 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2132 MESSAGE (" can not create BSplineSurface - create Bezier");
2134 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2135 double fp1,lp1,fp2,lp2;
2136 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2137 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2146 // get points from C1
2147 if (P1.Distance(P1C1)<1.e-6) {
2155 double step = (lp-fp)/(NbP-1);
2156 Points.SetValue(1,1,P1);
2158 for (n1=2; n1<NbP; n1++) {
2162 Points.SetValue(1,n1,P);
2164 Points.SetValue(1,NbP,P2);
2165 // get points from C3
2166 if (P4.Distance(P1C3)<1.e-6) {
2174 step = (lp-fp)/(NbP-1);
2175 Points.SetValue(NbP,1,P4);
2177 for (n1=2; n1<NbP; n1++) {
2181 Points.SetValue(NbP,n1,P);
2183 Points.SetValue(NbP,NbP,P3);
2184 // create isolines and get points from them
2185 for (n1=1; n1<=NbP; n1++) {
2186 gp_Pnt PI1 = Points.Value(1,n1);
2187 gp_Pnt PI2 = Points.Value(NbP,n1);
2188 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2189 HAP->SetValue(1,PI1);
2190 HAP->SetValue(2,PI2);
2191 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2192 anInt.Load(aDir1,aDir2);
2194 Handle(Geom_Curve) iso = anInt.Curve();
2195 fp = iso->FirstParameter();
2196 lp = iso->LastParameter();
2197 step = (lp-fp)/(NbP-1);
2199 TopoDS_Compound VComp;
2200 B.MakeCompound(VComp);
2201 for (n2=2; n2<NbP; n2++) {
2205 Points.SetValue(n2,n1,P);
2208 // create surface and face
2209 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2210 BS = new Geom_BezierSurface(Points);
2213 BRepBuilderAPI_MakeFace BB(BS,W);
2214 TopoDS_Face NewF = BB.Face();
2215 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2217 sff->FixOrientation();
2218 TopoDS_Face FixedFace = sff->Face();
2219 aNewFs.Append(FixedFace);
2220 VPE.Add(E1,FixedFace);
2221 //cout<<" face for edge "<<nbee<<" is created"<<endl;
2222 //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
2225 TopoDS_Shell aShell;
2226 B.MakeShell(aShell);
2227 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2228 B.Add(aShell,aNewFs(nf));
2233 // make sewing for this shell
2234 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2235 aSewing->SetTolerance(Precision::Confusion());
2236 aSewing->SetFaceMode(Standard_True);
2237 aSewing->SetFloatingEdgesMode(Standard_False);
2238 aSewing->SetNonManifoldMode(Standard_False);
2239 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2240 aSewing->Add(anExp.Current());
2243 MESSAGE (" shell for face "<<nbff<<" is created");
2244 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2245 //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
2246 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2247 aShell = TopoDS::Shell(aSewShape);
2248 GProp_GProps aSystem;
2249 BRepGProp::VolumeProperties(aShell, aSystem);
2250 if (aSystem.Mass()<0) {
2251 //cout<<"aSewShape is reversed"<<endl;
2254 if (BRep_Tool::IsClosed(aShell)) {
2255 TopoDS_Solid aSolid;
2256 B.MakeSolid(aSolid);
2257 B.Add(aSolid,aShell);
2258 B.Add(aComp,aSolid);
2259 MESSAGE (" solid for face "<<nbff<<" is created");
2262 B.Add(aComp,aShell);
2263 MESSAGE (" solid for face "<<nbff<<" is not created");
2267 B.Add(aComp,aShell);
2268 MESSAGE (" solid for face "<<nbff<<" is not created");
2270 //cout<<" solid for face "<<nbff<<" is created"<<endl;
2272 //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
2274 //TopoDS_Shell FixedShell = sfs->Shell();
2276 GProp_GProps aSystem;
2277 BRepGProp::VolumeProperties(FixedShell, aSystem);
2278 if (aSystem.Mass()<0) {
2279 //cout<<"aSewShape is reversed"<<endl;
2280 FixedShell.Reverse();
2282 if (BRep_Tool::IsClosed(FixedShell)) {
2283 TopoDS_Solid aSolid;
2284 B.MakeSolid(aSolid);
2285 B.Add(aSolid,aShell);
2286 B.Add(aComp,aSolid);
2289 B.Add(aComp,FixedShell);
2295 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
2299 //=======================================================================
2300 //function : CreatePipeBiNormalAlongVector
2301 //purpose : auxilary for Execute()
2302 //=======================================================================
2303 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2304 GEOMImpl_IPipe* aCI)
2306 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2308 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2309 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2310 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2311 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2313 if (aShapeBase.IsNull()) {
2314 if (aCIBN) delete aCIBN;
2315 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2318 // Make copy to prevent modifying of base object: 0021525
2319 BRepBuilderAPI_Copy Copy (aShapeBase);
2321 aShapeBase = Copy.Shape();
2324 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2327 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2328 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2330 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2333 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2334 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2335 aProf = wexp.Current();
2338 Standard_TypeMismatch::Raise
2339 ("MakePipe aborted : invalid type of base");
2341 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2342 PipeBuilder.Add(aProf);
2344 if (aShapeVec.IsNull()) {
2345 if (aCIBN) delete aCIBN;
2346 Standard_NullObject::Raise
2347 ("MakePipe aborted : null vector argument");
2349 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2350 Standard_TypeMismatch::Raise
2351 ("MakePipe aborted: invalid type of vector");
2352 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2353 TopoDS_Vertex V1, V2;
2354 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2355 if (V1.IsNull() || V2.IsNull())
2356 Standard_NullObject::Raise
2357 ("MakePipe aborted: vector is not defined");
2358 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2359 gp_Dir BiNormal(aVec);
2360 PipeBuilder.SetMode(BiNormal);
2362 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2364 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2365 PipeBuilder.MakeSolid();
2368 return PipeBuilder.Shape();
2371 //=======================================================================
2372 //function : Execute
2374 //=======================================================================
2375 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2377 if (Label().IsNull()) return 0;
2378 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2379 Standard_Integer aType = aFunction->GetType();
2381 GEOMImpl_IPipe* aCI = 0;
2382 if (aType == PIPE_BASE_PATH)
2383 aCI = new GEOMImpl_IPipe (aFunction);
2384 else if (aType == PIPE_DIFFERENT_SECTIONS)
2385 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
2386 else if (aType == PIPE_SHELL_SECTIONS)
2387 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2388 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2389 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2390 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2391 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
2395 TopoDS_Wire aWirePath;
2396 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2397 // working with path
2398 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2399 TopoDS_Shape aShapePath = aRefPath->GetValue();
2401 if (aShapePath.IsNull()) {
2402 MESSAGE ("Driver : path is null");
2403 if (aCI) delete aCI;
2404 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2409 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2410 TopTools_SequenceOfShape anEdges;
2411 TopExp_Explorer anExp;
2415 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2416 B.Add(W, anExp.Current());
2422 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2423 aWirePath = TopoDS::Wire(aShapePath);
2427 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2428 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2429 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2434 if (aCI) delete aCI;
2435 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2439 TopoDS_Shape aShape;
2441 if (aType == PIPE_BASE_PATH) {
2442 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2443 TopoDS_Shape aShapeBase;
2445 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2446 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2448 aShapeBase = Copy.Shape();
2450 if (aShapeBase.IsNull()) {
2451 if (aCI) delete aCI;
2452 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2456 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
2457 aShapeBase.ShapeType() == TopAbs_WIRE)
2459 TopoDS_Wire Profile;
2460 if (aShapeBase.ShapeType() == TopAbs_WIRE)
2461 Profile = TopoDS::Wire(aShapeBase);
2465 BB.MakeWire(Profile);
2466 BB.Add(Profile, aShapeBase);
2469 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
2470 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
2471 if (FaceBuilder.IsDone())
2472 Sweep.SetMode(FaceBuilder.Face());
2475 Standard_Boolean isDone = BuildPipeShell(Sweep);
2479 if (aCI) delete aCI;
2480 Standard_ConstructionError::Raise("MakePipeShell failed");
2483 aShape = Sweep.Shape(); //result is good
2488 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
2489 BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode);
2491 if (aMkPipe.IsDone()) {
2492 aShape = aMkPipe.Shape();
2493 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
2494 // Try to use Descrete Trihedron mode.
2495 BRepOffsetAPI_MakePipe aMkPipeDescrete
2496 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron);
2498 if (aMkPipeDescrete.IsDone()) {
2499 aShape = aMkPipeDescrete.Shape();
2505 //building pipe with different sections
2506 else if (aType == PIPE_DIFFERENT_SECTIONS) {
2507 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
2508 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
2509 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
2510 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
2511 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
2517 Standard_Integer nbBases = aBasesObjs->Length();
2518 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
2520 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
2521 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
2524 for (i = 1; i <= nbBases; i++) {
2525 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
2526 if (anItem.IsNull())
2528 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
2529 if (aRefBase.IsNull())
2531 if (aRefBase->GetValue().IsNull())
2534 aHSeqBases->Append(aRefBase->GetValue());
2536 for (i = 1; i <= nbLocs; i++) {
2537 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
2538 if (anItemLoc.IsNull())
2540 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
2541 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
2542 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
2545 aHSeqLocs->Append(aShapeLoc);
2548 aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
2551 //building pipe with shell sections
2552 else if (aType == PIPE_SHELL_SECTIONS) {
2553 aShape = CreatePipeForShellSections(aWirePath,aCI);
2556 //building pipe shell sections without path
2557 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
2558 aShape = CreatePipeShellsWithoutPath(aCI);
2561 //building a pipe with constant bi-normal along given vector
2562 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
2563 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
2571 if (aShape.IsNull()) return 0;
2573 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
2574 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
2576 if (aType != PIPE_BASE_PATH &&
2577 aType != PIPE_SHELLS_WITHOUT_PATH) {
2578 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
2579 if (anExpV.More()) {
2580 Standard_Real aVertMaxTol = -RealLast();
2581 for (; anExpV.More(); anExpV.Next()) {
2582 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
2583 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
2584 if (aTol > aVertMaxTol)
2587 aVertMaxTol += Precision::Confusion();
2588 aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
2589 //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
2593 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
2594 aFunction->SetValue(aRes);
2596 log.SetTouched(Label());
2600 //================================================================================
2602 * \brief Returns a name of creation operation and names and values of creation parameters
2604 //================================================================================
2606 bool GEOMImpl_PipeDriver::
2607 GetCreationInformation(std::string& theOperationName,
2608 std::vector<GEOM_Param>& theParams)
2610 if (Label().IsNull()) return 0;
2611 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
2612 Standard_Integer aType = function->GetType();
2615 case PIPE_BASE_PATH:
2617 theOperationName = "PIPE";
2618 GEOMImpl_IPipe aCI( function );
2619 AddParam( theParams, "Base Object", aCI.GetBase() );
2620 AddParam( theParams, "Path Object", aCI.GetPath() );
2623 case PIPE_BI_NORMAL_ALONG_VECTOR:
2625 theOperationName = "PIPE";
2626 GEOMImpl_IPipeBiNormal aCI( function );
2627 AddParam( theParams, "Base Object", aCI.GetBase() );
2628 AddParam( theParams, "Path Object", aCI.GetPath() );
2629 AddParam( theParams, "BiNormal", aCI.GetVector() );
2632 case PIPE_DIFFERENT_SECTIONS:
2634 theOperationName = "PIPE";
2635 GEOMImpl_IPipeDiffSect aCI( function );
2636 AddParam( theParams, "Bases", aCI.GetBases() );
2637 AddParam( theParams, "Locations", aCI.GetLocations() );
2638 AddParam( theParams, "Path", aCI.GetPath() );
2639 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2640 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2643 case PIPE_SHELL_SECTIONS:
2645 theOperationName = "PIPE";
2646 GEOMImpl_IPipeShellSect aCI( function );
2647 AddParam( theParams, "Bases", aCI.GetBases() );
2648 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
2649 AddParam( theParams, "Locations", aCI.GetLocations() );
2650 AddParam( theParams, "Path", aCI.GetPath() );
2651 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
2652 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
2655 case PIPE_SHELLS_WITHOUT_PATH:
2657 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
2658 GEOMImpl_IPipeShellSect aCI( function );
2659 AddParam( theParams, "Bases", aCI.GetBases() );
2660 AddParam( theParams, "Locations", aCI.GetLocations() );
2670 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
2671 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);